bangonit 0.3.4 → 0.4.1
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 +24 -33
- package/app/desktopapp/dist/main/index.js +4 -2
- package/app/desktopapp/dist/main/ipc.js +96 -20
- package/app/desktopapp/dist/main/preload.js +4 -3
- package/app/desktopapp/dist/main/tabs.js +43 -3
- package/app/replay/dist/replay.css +1 -1
- package/app/replay/dist/replay.js +24 -24
- package/app/webapp/.next/standalone/app/webapp/.next/BUILD_ID +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/app-build-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/app-path-routes-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/build-manifest.json +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/prerender-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/_not-found.rsc +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app/page.js +3 -3
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app/page_client-reference-manifest.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/app.rsc +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/index.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/index.rsc +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app/page.js +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/app-paths-manifest.json +2 -2
- package/app/webapp/.next/standalone/app/webapp/.next/server/chunks/124.js +9 -9
- package/app/webapp/.next/standalone/app/webapp/.next/server/chunks/708.js +5 -4
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages/404.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/pages/500.html +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/server/server-reference-manifest.json +1 -1
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/app/page-74ec5ee2f3d3d4a0.js +1 -0
- package/app/webapp/.next/standalone/package.json +7 -4
- package/app/webapp/.next/static/chunks/app/app/page-74ec5ee2f3d3d4a0.js +1 -0
- package/app/webapp/src/shared/api/chat.ts +7 -4
- package/app/webapp/src/shared/components/AppShell.tsx +6 -5
- package/app/webapp/src/shared/components/SessionView.tsx +4 -3
- package/app/webapp/src/shared/lib/browser/index.ts +17 -27
- package/app/webapp/src/shared/lib/browser/recorder.ts +13 -4
- package/app/webapp/src/shared/lib/browser/snapshot.ts +25 -5
- package/app/webapp/src/shared/lib/browser/types.ts +21 -6
- package/app/webapp/src/shared/types/global.d.ts +6 -4
- package/bin/src/cli/bangonit.js +19 -11
- package/package.json +7 -4
- package/scripts/regen-replays.sh +101 -0
- package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/app/page-df00a757f649931a.js +0 -1
- package/app/webapp/.next/static/chunks/app/app/page-df00a757f649931a.js +0 -1
- /package/app/webapp/.next/standalone/app/webapp/.next/static/{bBZVP6sUilA3wyt0vYqDc → CfMl7etZBP4Q0LYMXf4ZP}/_buildManifest.js +0 -0
- /package/app/webapp/.next/standalone/app/webapp/.next/static/{bBZVP6sUilA3wyt0vYqDc → CfMl7etZBP4Q0LYMXf4ZP}/_ssgManifest.js +0 -0
- /package/app/webapp/.next/static/{bBZVP6sUilA3wyt0vYqDc → CfMl7etZBP4Q0LYMXf4ZP}/_buildManifest.js +0 -0
- /package/app/webapp/.next/static/{bBZVP6sUilA3wyt0vYqDc → CfMl7etZBP4Q0LYMXf4ZP}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";exports.id=708,exports.ids=[708],exports.modules={5708:(e,t,s)=>{s.d(t,{V:()=>y,u:()=>b});var o=s(4523),n=s(6365),a=s(1041),r=s(2048),i=s.n(r),l=s(5315),c=s.n(l),p=s(9763);let u=p.VK("type",[p.Ry({type:p.i0("not_changed")}),p.Ry({type:p.i0("changed"),base64:p.Z_()})]),h=p.Ry({textOutput:p.Z_(),imageOutput:u.nullable()});Promise.resolve();let d={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Client-Platform"};function y(){return{OPTIONS:async()=>new Response(null,{status:204,headers:d}),POST:async e=>{let t=await e.json(),s=process.env.ANTHROPIC_API_KEY;if(!s)return new Response(JSON.stringify({error:"Server API key not configured"}),{status:500,headers:{"Content-Type":"application/json",...d}});let r=e.headers.get("x-client-platform")||"",l=process.cwd(),p=(0,o.D3)({apiKey:s}),u={browser:(0,n.w3)({description:"Control the browser. Pass an array of actions to execute sequentially. Set 'observe' to observe the page after actions complete. The system waits for network idle before observation.",inputSchema:(0,n.fB)({type:"object",properties:{observe:{type:"string",enum:["snapshot","snapshot_and_screenshot"],description:"How to observe the page after actions. 'snapshot' takes a fast accessibility snapshot with element refs. 'snapshot_and_screenshot' also takes a screenshot analyzed by a vision subagent (slower — use only when the snapshot doesn't have the info you need)."},prompts:{type:"array",items:{type:"string"},description:"Questions for screenshot vision analysis (only used with observe: 'snapshot_and_screenshot')"},actions:{type:"array",items:{type:"object",properties:{action:{type:"string",enum:["navigate","back","forward","mouse","type","press","
|
|
1
|
+
"use strict";exports.id=708,exports.ids=[708],exports.modules={5708:(e,t,s)=>{s.d(t,{V:()=>y,u:()=>b});var o=s(4523),n=s(6365),a=s(1041),r=s(2048),i=s.n(r),l=s(5315),c=s.n(l),p=s(9763);let u=p.VK("type",[p.Ry({type:p.i0("not_changed")}),p.Ry({type:p.i0("changed"),base64:p.Z_()})]),h=p.Ry({textOutput:p.Z_(),imageOutput:u.nullable()});Promise.resolve();let d={"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization, X-Client-Platform"};function y(){return{OPTIONS:async()=>new Response(null,{status:204,headers:d}),POST:async e=>{let t=await e.json(),s=process.env.ANTHROPIC_API_KEY;if(!s)return new Response(JSON.stringify({error:"Server API key not configured"}),{status:500,headers:{"Content-Type":"application/json",...d}});let r=e.headers.get("x-client-platform")||"",l=process.cwd(),p=(0,o.D3)({apiKey:s}),u={browser:(0,n.w3)({description:"Control the browser. Pass an array of actions to execute sequentially. Set 'observe' to observe the page after actions complete. The system waits for network idle before observation.",inputSchema:(0,n.fB)({type:"object",properties:{observe:{type:"string",enum:["snapshot","snapshot_and_screenshot"],description:"How to observe the page after actions. 'snapshot' takes a fast accessibility snapshot with element refs. 'snapshot_and_screenshot' also takes a screenshot analyzed by a vision subagent (slower — use only when the snapshot doesn't have the info you need)."},prompts:{type:"array",items:{type:"string"},description:"Questions for screenshot vision analysis (only used with observe: 'snapshot_and_screenshot')"},actions:{type:"array",items:{type:"object",properties:{action:{type:"string",enum:["navigate","back","forward","mouse","type","press","upload","tabs","wait","close"],description:"The browser action to perform"},url:{type:"string",description:"URL for navigate or new tab"},text:{type:"string",description:"Text to type"},key:{type:"string",description:"Key combo for press"},mouseActions:{type:"array",items:{type:"object",properties:{action:{type:"string",enum:["click","dblclick","down","move","up","wheel","wait"]},ref:{type:"string",description:"Element ref from snapshot"},x:{type:"number"},y:{type:"number"},dx:{type:"number"},dy:{type:"number"},ms:{type:"number"}},required:["action"]}},paths:{type:"array",items:{type:"string"},description:"File paths for upload"},cancel:{type:"boolean",description:"Cancel file picker"},tabAction:{type:"string",enum:["list","new","close","select"]},tabId:{type:"number"},timeout:{type:"number"},width:{type:"number"},height:{type:"number"}},required:["action"]}}},required:["actions"]}),toModelOutput({output:e}){let t=h.parse(JSON.parse(e));return t.imageOutput?"not_changed"===t.imageOutput.type?{type:"content",value:[{type:"text",text:t.textOutput+"\n\n[screenshot did not change since last screenshot]"}]}:{type:"content",value:[{type:"text",text:t.textOutput},{type:"image-data",mediaType:"image/jpeg",data:t.imageOutput.base64}]}:{type:"content",value:[{type:"text",text:t.textOutput}]}}}),todos:(0,n.w3)({description:"Track progress on multi-step tasks. Call with the FULL list of todos to update, or omit 'todos' to read the current list.",inputSchema:(0,n.fB)({type:"object",properties:{todos:{type:"array",items:{type:"object",properties:{content:{type:"string"},status:{type:"string",enum:["pending","in_progress","completed"]}},required:["content","status"]}}}})}),report_result:(0,n.w3)({description:"Report the final test result. You MUST call this exactly once at the end of every test run. Pass 'pass' if all test steps succeeded, or 'fail' with a summary of what went wrong.",inputSchema:(0,n.fB)({type:"object",properties:{result:{type:"string",enum:["pass","fail"],description:"Whether the test passed or failed"},summary:{type:"string",description:"Brief summary of test results. For failures, describe what went wrong."}},required:["result","summary"]})})},y=await (0,a.bS)(t.messages,{tools:u});return(0,a.kP)({model:p("claude-sonnet-4-6"),system:function(e,t){let s=e.toLowerCase().includes("mac"),o=s?"Meta":"Control",n=function(e){try{let t=function(e){let t=e;for(;;){if(i().existsSync(c().join(t,".bangonit")))return c().join(t,".bangonit");if(i().existsSync(c().join(t,".git")))return null;let e=c().dirname(t);if(e===t)return null;t=e}}(e);if(!t)return"";return i().readFileSync(c().join(t,"system_prompt.md"),"utf-8").trim()}catch(e){return console.error(e),""}}(t),a=`You are Bang On It!, a QA testing agent that executes test plans by controlling a browser.
|
|
2
2
|
|
|
3
3
|
You run test plans autonomously. When you have finished executing all test steps, you MUST call the report_result tool to report whether the test passed or failed. This is mandatory — every test run must end with a report_result call.
|
|
4
4
|
|
|
@@ -21,7 +21,8 @@ Actions:
|
|
|
21
21
|
IMPORTANT: Mouse actions move a real cursor across the screen. The cursor travels from its current position to the target, which may trigger hover effects (tooltips, dropdowns, highlights) on elements along the path. If a hover side-effect disrupts your intended action (e.g. a menu opens over your click target), take a fresh snapshot and retry. You can also use this to your advantage — use "move" to intentionally hover over elements to reveal tooltips or dropdown menus.
|
|
22
22
|
type <text> — type text at cursor (keystrokes)
|
|
23
23
|
press <key> — press a key or combo (Enter, Tab, ${o}+a, Shift+Enter)
|
|
24
|
-
|
|
24
|
+
upload --paths=["/path/to/file"] — upload files to an open file picker (the snapshot will tell you when a file picker is open)
|
|
25
|
+
upload --cancel=true — cancel/dismiss an open file picker
|
|
25
26
|
tabs --action=list — list open tabs
|
|
26
27
|
tabs --action=new --url=<url> — open new tab
|
|
27
28
|
tabs --action=select --tabId=<id> — switch tab
|
|
@@ -61,7 +62,7 @@ Good — drag from one point to another:
|
|
|
61
62
|
{ actions: [{"action":"mouse","mouseActions":[{"action":"down","x":100,"y":200},{"action":"move","x":300,"y":400},{"action":"up","x":300,"y":400}]}] }
|
|
62
63
|
|
|
63
64
|
## Dialogs and file pickers
|
|
64
|
-
JavaScript dialogs are automatically handled: alert() is suppressed, confirm() returns true, and prompt() returns the default value.
|
|
65
|
+
JavaScript dialogs are automatically handled: alert() is suppressed, confirm() returns true, and prompt() returns the default value. File picker dialogs are intercepted — they will not visually appear, but the snapshot will show "[File picker is open]" when one is triggered. Use the "upload" action to provide file paths or cancel the picker.
|
|
65
66
|
|
|
66
67
|
## Todo tracking
|
|
67
68
|
For tasks with 3+ distinct steps, call the todos tool to show progress. Call it with the FULL list each time:
|
|
@@ -71,7 +72,7 @@ For tasks with 3+ distinct steps, call the todos tool to show progress. Call it
|
|
|
71
72
|
Keep todos short (5-10 words each). The user watches your progress in real time, so update todos promptly after each step finishes.
|
|
72
73
|
To read the current todo list, call todos without the "todos" parameter. Only you can write todos, so you normally don't need to read them — use this only when you've lost track (e.g. after context was compacted).
|
|
73
74
|
|
|
74
|
-
Be concise. The user watches your actions in real time.`;return n&&(a=`## Project Instructions
|
|
75
|
+
Be concise and token-efficient. Don't narrate every step — just act. Summarize successes and failures briefly (e.g. "3 todos added, footer shows correct count" not a blow-by-blow of each click). The user watches your actions in real time.`;return n&&(a=`## Project Instructions
|
|
75
76
|
${n}
|
|
76
77
|
|
|
77
78
|
${a}`),a}(r,l),providerOptions:{anthropic:{cacheControl:{type:"ephemeral"},contextManagement:{edits:[{type:"compact_20260112",trigger:{type:"input_tokens",value:12e4},instructions:"Summarize the conversation concisely. Preserve: the test plan, all URLs visited, current page/tab state, actions completed, current test state (done/in-progress/remaining), errors and resolutions, key decisions made. Include exact URLs, filenames, and values."}]}}},messages:y,tools:u,stopWhen:(0,a.vk)(50)}).toUIMessageStreamResponse({headers:d})}}}var m=s(1379);let f=`You are a vision subagent for Bang On It!, an AI QA testing tool.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/85c115515088d5dd.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-9e4fd47eb2c72de4.js"/><script src="/_next/static/chunks/1dd3208c-2143388ffa327752.js" async=""></script><script src="/_next/static/chunks/528-31e5ce0646826d75.js" async=""></script><script src="/_next/static/chunks/main-app-106dd83f859b9dfa.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Bang On It!</title><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-9e4fd47eb2c72de4.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/85c115515088d5dd.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[1815,[],\"\"]\n4:I[5092,[],\"\"]\n5:I[2023,[],\"\"]\nb:I[1584,[],\"\"]\n6:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n7:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n8:{\"display\":\"inline-block\"}\n9:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nc:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/85c115515088d5dd.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-9e4fd47eb2c72de4.js"/><script src="/_next/static/chunks/1dd3208c-2143388ffa327752.js" async=""></script><script src="/_next/static/chunks/528-31e5ce0646826d75.js" async=""></script><script src="/_next/static/chunks/main-app-106dd83f859b9dfa.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Bang On It!</title><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-9e4fd47eb2c72de4.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/85c115515088d5dd.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[1815,[],\"\"]\n4:I[5092,[],\"\"]\n5:I[2023,[],\"\"]\nb:I[1584,[],\"\"]\n6:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n7:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n8:{\"display\":\"inline-block\"}\n9:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nc:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"CfMl7etZBP4Q0LYMXf4ZP\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/85c115515088d5dd.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$6\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$7\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$9\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Bang On It!\"}]]\n3:null\n"])</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>500: Internal Server Error</title><meta name="next-head-count" content="3"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-9e4fd47eb2c72de4.js" defer=""></script><script src="/_next/static/chunks/framework-3664cab31236a9fa.js" defer=""></script><script src="/_next/static/chunks/main-7b05b3530a4fe793.js" defer=""></script><script src="/_next/static/chunks/pages/_app-10a93ab5b7c32eb3.js" defer=""></script><script src="/_next/static/chunks/pages/_error-2d792b2a41857be4.js" defer=""></script><script src="/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>500: Internal Server Error</title><meta name="next-head-count" content="3"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-9e4fd47eb2c72de4.js" defer=""></script><script src="/_next/static/chunks/framework-3664cab31236a9fa.js" defer=""></script><script src="/_next/static/chunks/main-7b05b3530a4fe793.js" defer=""></script><script src="/_next/static/chunks/pages/_app-10a93ab5b7c32eb3.js" defer=""></script><script src="/_next/static/chunks/pages/_error-2d792b2a41857be4.js" defer=""></script><script src="/_next/static/CfMl7etZBP4Q0LYMXf4ZP/_buildManifest.js" defer=""></script><script src="/_next/static/CfMl7etZBP4Q0LYMXf4ZP/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"CfMl7etZBP4Q0LYMXf4ZP","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"node":{},"edge":{},"encryptionKey":"
|
|
1
|
+
{"node":{},"edge":{},"encryptionKey":"aABbKuFTQX60aMuGUs59W82UtTanuDXp8NUg91yDjFo="}
|
package/app/webapp/.next/standalone/app/webapp/.next/static/chunks/app/app/page-74ec5ee2f3d3d4a0.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[191],{6421:function(e,t,n){Promise.resolve().then(n.bind(n,2953))},2953:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return L}});var a=n(7573),r=n(7653),i=n(774),o=n(1446),l=n(2574),s=n(3334);function c(e){let{agentId:t}=e,[n,i]=(0,r.useState)(null),[o,l]=(0,r.useState)(!1),[s,c]=(0,r.useState)(!1),[u,d]=(0,r.useState)([]),p=(0,r.useRef)(),h=(0,r.useRef)(0),m=(0,r.useCallback)(()=>{l(!0),clearTimeout(p.current),p.current=setTimeout(()=>l(!1),2e3)},[]);return((0,r.useEffect)(()=>{var e,n,a;let r=[];return r.push(null===(e=window.bangonit)||void 0===e?void 0:e.onCursorMove(e=>{e.agentId===t&&(i({x:e.x,y:e.y}),m())})),r.push(null===(n=window.bangonit)||void 0===n?void 0:n.onCursorDown(e=>{if(e.agentId!==t)return;i({x:e.x,y:e.y}),c(!0),m();let n=++h.current;d(t=>[...t,{id:n,x:e.x,y:e.y}]),setTimeout(()=>{d(e=>e.filter(e=>e.id!==n))},400)})),r.push(null===(a=window.bangonit)||void 0===a?void 0:a.onCursorUp(e=>{e.agentId===t&&(c(!1),m())})),()=>{r.forEach(e=>null==e?void 0:e()),clearTimeout(p.current)}},[t,m]),n)?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("svg",{width:"28",height:"28",viewBox:"0 0 24 24",className:"pointer-events-none absolute z-20",style:{left:n.x,top:n.y,transform:"translate(-2px, -1px) ".concat(s?"scale(0.8)":"scale(1)"),transition:"left 30ms linear, top 30ms linear, transform 80ms ease-out, opacity 400ms ease-out",opacity:o?1:0,filter:"drop-shadow(0 1px 2px rgba(0,0,0,0.5))"},children:(0,a.jsx)("path",{d:"M5 3l14 8.5-6.5 1.5-3.5 6z",fill:"white",stroke:"black",strokeWidth:"1.5",strokeLinejoin:"round"})}),u.map(e=>(0,a.jsxs)("span",{children:[(0,a.jsx)("span",{className:"pointer-events-none absolute z-20 rounded-full bg-blue-400/50",style:{left:e.x,top:e.y,width:0,height:0,transform:"translate(-50%, -50%)",animation:"cursor-ripple ".concat(400,"ms ease-out forwards")}}),(0,a.jsx)("span",{className:"pointer-events-none absolute z-20 rounded-full border-2 border-blue-400/60",style:{left:e.x,top:e.y,width:0,height:0,transform:"translate(-50%, -50%)",animation:"cursor-ripple-ring ".concat(400,"ms ease-out forwards")}})]},e.id)),(0,a.jsx)("style",{children:"\n @keyframes cursor-ripple {\n 0% { width: 0; height: 0; opacity: 0.8; }\n 100% { width: 48px; height: 48px; opacity: 0; }\n }\n @keyframes cursor-ripple-ring {\n 0% { width: 0; height: 0; opacity: 0.9; }\n 100% { width: 64px; height: 64px; opacity: 0; }\n }\n "})]}):null}async function u(e,t,n,a){let[{result:r},i,o,{result:l}]=await Promise.all([window.bangonit.cdpSend(e,"Runtime.evaluate",{expression:"\n(function() {\n var MAX_CHARS = 60000;\n var MAX_ELEMENTS = 5000;\n var MAX_DEPTH = 1500;\n var totalChars = 0;\n var visited = 0;\n var truncated = false;\n var refCounter = 0;\n\n window.__dmjRefs = new Map();\n\n var SKIP_TAGS = {SCRIPT:1,STYLE:1,NOSCRIPT:1,SVG:1,PATH:1,META:1,LINK:1,TEMPLATE:1,IFRAME:1,BR:1,HR:1,WBR:1,CANVAS:1,VIDEO:1,AUDIO:1,MAP:1,AREA:1,PICTURE:1,SOURCE:1,TRACK:1,OBJECT:1,EMBED:1};\n var INTERACTIVE_ROLES = {button:1,link:1,textbox:1,checkbox:1,radio:1,combobox:1,menuitem:1,tab:1,switch:1,option:1};\n var INPUT_ROLE = {checkbox:'checkbox',radio:'radio',submit:'button',button:'button',search:'searchbox',file:'file'};\n var TAG_ROLE = {A:'link',BUTTON:'button',SELECT:'combobox',TEXTAREA:'textbox',IMG:'img',H1:'heading',H2:'heading',H3:'heading',H4:'heading',H5:'heading',H6:'heading',NAV:'navigation',MAIN:'main',FORM:'form',TABLE:'table',UL:'list',OL:'list',LI:'listitem'};\n\n function isVisible(el) {\n if (el.hidden || el.getAttribute('aria-hidden') === 'true') return false;\n if (!el.offsetParent && el.tagName !== 'BODY' && el.tagName !== 'HTML') {\n var pos = getComputedStyle(el).position;\n if (pos !== 'fixed' && pos !== 'sticky') return false;\n }\n var s = el.style;\n if (s.display === 'none' || s.visibility === 'hidden') return false;\n return true;\n }\n\n function isInteractive(el) {\n var tag = el.tagName;\n if (tag === 'A' || tag === 'BUTTON' || tag === 'SELECT' || tag === 'TEXTAREA') return true;\n if (tag === 'INPUT' && el.type !== 'hidden') return true;\n var role = el.getAttribute('role');\n if (role && INTERACTIVE_ROLES[role]) return true;\n var tabindex = el.getAttribute('tabindex');\n if (el.onclick || (tabindex !== null && tabindex >= '0')) return true;\n if (el.contentEditable === 'true') return true;\n return false;\n }\n\n function getRole(el) {\n var r = el.getAttribute('role');\n if (r) return r;\n if (el.tagName === 'INPUT') return INPUT_ROLE[(el.type||'text').toLowerCase()] || 'textbox';\n return TAG_ROLE[el.tagName] || null;\n }\n\n function getLabel(el) {\n return (el.getAttribute('aria-label') || el.getAttribute('placeholder') || el.getAttribute('alt') || el.getAttribute('title') || '').slice(0, 50);\n }\n\n function directText(el) {\n var t = '';\n for (var n = el.firstChild; n; n = n.nextSibling) {\n if (n.nodeType === 3) t += n.data;\n if (t.length > 60) break;\n }\n return t.trim().replace(/\\s+/g, ' ').slice(0, 60);\n }\n\n function walk(el, depth) {\n if (truncated || !el || el.nodeType !== 1) return '';\n if (SKIP_TAGS[el.tagName]) return '';\n if (!isVisible(el)) return '';\n if (depth > MAX_DEPTH) return '';\n if (++visited > MAX_ELEMENTS) { truncated = true; return ''; }\n\n var role = getRole(el);\n var interactive = isInteractive(el);\n var showThis = !!(role || interactive);\n var lines = [];\n\n if (showThis) {\n var label = getLabel(el);\n var dtext = directText(el);\n var line = '[' + (role || el.tagName.toLowerCase());\n var txt = label || dtext;\n if (txt) line += ' \"' + txt.replace(/\"/g, \"'\") + '\"';\n if (interactive) {\n var ref = 'e' + (++refCounter);\n window.__dmjRefs.set(ref, new WeakRef(el));\n line += ' ref=' + ref;\n }\n line += ']';\n if (el === document.activeElement) line += ' [focused]';\n if ((el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') && el.value) line += ' val=\"' + el.value.slice(0,40) + '\"';\n if (el.tagName === 'INPUT' && (el.type === 'checkbox' || el.type === 'radio')) line += el.checked ? ' [x]' : ' [ ]';\n\n totalChars += line.length;\n if (totalChars > MAX_CHARS) { truncated = true; return ''; }\n lines.push(line);\n }\n\n for (var c = el.firstElementChild; c; c = c.nextElementSibling) {\n if (truncated) break;\n var out = walk(c, showThis ? depth + 1 : depth);\n if (out) lines.push(showThis ? out.split('\\n').map(function(l){return ' '+l}).join('\\n') : out);\n }\n\n if (!showThis) {\n var dt = directText(el);\n if (dt.length > 2) {\n totalChars += dt.length;\n if (totalChars > MAX_CHARS) { truncated = true; return ''; }\n lines.push('\"' + dt + '\"');\n }\n }\n\n return lines.join('\\n');\n }\n\n var tree = walk(document.body, 0);\n var h = 'URL: ' + location.href + '\\nTitle: ' + document.title;\n if (truncated) h += '\\n[TRUNCATED - page too large]';\n return h + '\\n\\n' + tree;\n})()\n",returnByValue:!0}),window.bangonit.getDownloads(e),window.bangonit.getFileChooserState(e),window.bangonit.cdpSend(e,"Runtime.evaluate",{expression:"JSON.stringify({w:window.innerWidth,h:window.innerHeight})",returnByValue:!0})]),s=(()=>{try{return JSON.parse(l.value)}catch(e){return null}})(),c=s?"\nViewport: ".concat(s.w,"x").concat(s.h):"",u=(r.value||"Empty page")+"\n\nMouse position: ".concat(t,",").concat(n).concat(c)+a;if(o.open&&(u+="\n\n[File picker is open — use upload action with paths to select files, or cancel: true to dismiss]"),i.length>0){let e=i.map(e=>"- ".concat(e.filename," (").concat(e.bytes," bytes) [").concat(e.state,"]"));u+="\n\nDownloads:\n".concat(e.join("\n"))}return u}async function d(e,t,n){let a=window.bangonit;if(t.ref){let{result:i}=await a.cdpSend(e,"Runtime.evaluate",{expression:'(function() { var r = window.__dmjRefs && window.__dmjRefs.get("'.concat(t.ref,'"); return r ? r.deref() || null : null; })()'),returnByValue:!1});if(!i.objectId)throw Error('Element ref "'.concat(t.ref,'" not found — take a new snapshot'));try{let{model:r}=await a.cdpSend(e,"DOM.getBoxModel",{objectId:i.objectId}),o=r.content,l=Math.round((o[0]+o[2]+o[4]+o[6])/4),s=Math.round((o[1]+o[3]+o[5]+o[7])/4);if(n){let{result:t}=await a.cdpSend(e,"Runtime.evaluate",{expression:"JSON.stringify({ w: window.innerWidth, h: window.innerHeight })",returnByValue:!0}),n=JSON.parse(t.value);if(l<0||l>n.w||s<0||s>n.h){await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:'function() { this.scrollIntoView({ block: "center", inline: "center", behavior: "instant" }); }',returnByValue:!0}),await new Promise(e=>setTimeout(e,100));let{model:t}=await a.cdpSend(e,"DOM.getBoxModel",{objectId:i.objectId}),n=t.content;l=Math.round((n[0]+n[2]+n[4]+n[6])/4),s=Math.round((n[1]+n[3]+n[5]+n[7])/4)}}else if(l<0||s<0){let{result:n}=await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:"function() {\n var r = this.getBoundingClientRect();\n return { top: r.top, bottom: r.bottom, left: r.left, right: r.right, vh: window.innerHeight, vw: window.innerWidth };\n }",returnByValue:!0}),r=n.value;if(r){let e=r.top<0?Math.round(r.top-100):r.bottom>r.vh?Math.round(r.bottom-r.vh+100):0,n=0!==e?" Scroll ".concat(e>0?"down":"up"," ~").concat(Math.abs(e),"px (wheel dy=").concat(e," at current mouse position)"):"";throw Error('Element ref "'.concat(t.ref,'" is not in the viewport and cannot auto-scroll because this batch contains x,y coordinates that would be invalidated by scrolling.').concat(n))}}return{x:l,y:s}}catch(o){var r;if(null===(r=o.message)||void 0===r?void 0:r.includes("not in the viewport"))throw o;if(n)try{await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:'function() { this.scrollIntoView({ block: "center", inline: "center", behavior: "instant" }); }',returnByValue:!0}),await new Promise(e=>setTimeout(e,100));let{model:t}=await a.cdpSend(e,"DOM.getBoxModel",{objectId:i.objectId}),n=t.content;return{x:Math.round((n[0]+n[2]+n[4]+n[6])/4),y:Math.round((n[1]+n[3]+n[5]+n[7])/4)}}catch(e){throw Error('Element ref "'.concat(t.ref,'" could not be scrolled into view'))}try{let{result:n}=await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:"function() {\n var r = this.getBoundingClientRect();\n return { top: r.top, bottom: r.bottom, left: r.left, right: r.right, vh: window.innerHeight, vw: window.innerWidth };\n }",returnByValue:!0}),r=n.value;if(r){let e=r.top<0?Math.round(r.top-100):r.bottom>r.vh?Math.round(r.bottom-r.vh+100):0,n=0!==e?" Scroll ".concat(e>0?"down":"up"," ~").concat(Math.abs(e),"px (wheel dy=").concat(e," at current mouse position)"):"";throw Error('Element ref "'.concat(t.ref,'" is not in the viewport and cannot auto-scroll because this batch contains x,y coordinates that would be invalidated by scrolling.').concat(n))}}catch(e){if(e.message.includes("not in the viewport"))throw e}throw Error('Element ref "'.concat(t.ref,'" is not visible in the viewport — use only refs or scroll manually first'))}finally{a.cdpSend(e,"Runtime.releaseObject",{objectId:i.objectId}).catch(e=>console.error(e))}}return{x:t.x,y:t.y}}async function p(e,t,n,a,r,i){let o=window.bangonit,l=Math.hypot(a-t,r-n);if(l<1){null==i||i(a,r);return}let s=Math.min(Math.max(Math.round(l/15),3),40),c=Math.min(Math.max(.8*l,30),300);for(let l=1;l<=s;l++){let u=l/s,d=u<.5?4*u*u*u:1-Math.pow(-2*u+2,3)/2,p=Math.round(t+(a-t)*d),h=Math.round(n+(r-n)*d);await o.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseMoved",x:p,y:h}),null==i||i(p,h),l<s&&await new Promise(e=>setTimeout(e,c/s))}}async function h(e,t,n,a,r){var i,o,l,s,c,u,h,m;let b=window.bangonit;null===(i=r.onMouseLock)||void 0===i||i.call(r);let w=!t.some(e=>"wait"!==e.action&&void 0!==e.x),f=n,g=a;try{let n=[];for(let a of t){if("wait"===a.action){await new Promise(e=>setTimeout(e,Math.min(a.ms||100,2e3))),n.push("wait(".concat(a.ms||100,"ms)"));continue}let t=a.ref?{ref:a.ref}:{x:a.x,y:a.y},i=await d(e,t,w),m="".concat(i.x,",").concat(i.y),{x:v,y:x}=i;switch(a.action){case"down":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,null===(o=r.onCursorDown)||void 0===o||o.call(r,v,x),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:1}),n.push("down(".concat(m,")"));break;case"move":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,n.push("move(".concat(m,")"));break;case"up":await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:1}),null===(l=r.onCursorUp)||void 0===l||l.call(r,v,x),n.push("up(".concat(m,")"));break;case"click":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,null===(s=r.onCursorDown)||void 0===s||s.call(r,v,x),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:1}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:1}),null===(c=r.onCursorUp)||void 0===c||c.call(r,v,x),n.push("click(".concat(m,")"));break;case"dblclick":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,null===(u=r.onCursorDown)||void 0===u||u.call(r,v,x),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:1}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:1}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:2}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:2}),null===(h=r.onCursorUp)||void 0===h||h.call(r,v,x),n.push("dblclick(".concat(m,")"));break;case"wheel":{await p(e,f,g,v,x,r.onCursorMove),f=v,g=x;let t=a.dx||0,i=a.dy||0;await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseWheel",x:v,y:x,deltaX:t,deltaY:i}),n.push("wheel(".concat(m,",").concat(t,",").concat(i,")"))}}}return{result:"Mouse: ".concat(n.join(" → ")),mouseX:f,mouseY:g}}finally{null===(m=r.onMouseUnlock)||void 0===m||m.call(r)}}async function m(e,t){let n=window.bangonit;for(let a of t)await n.sendInputEvent(e,{type:"keyDown",keyCode:a}),await n.sendInputEvent(e,{type:"char",keyCode:a}),await n.sendInputEvent(e,{type:"keyUp",keyCode:a}),await new Promise(e=>setTimeout(e,30+70*Math.random()));return'Typed "'.concat(t.slice(0,50),'"')}async function b(e,t){let n=window.bangonit,a=t.split("+"),r=a.pop(),i=a.map(e=>e.toLowerCase()),o=[];for(let e of i)"control"===e||"ctrl"===e?o.push("control"):"meta"===e||"command"===e||"cmd"===e?o.push("meta"):"alt"===e||"option"===e?o.push("alt"):"shift"===e&&o.push("shift");return await n.sendInputEvent(e,{type:"keyDown",keyCode:r,modifiers:o}),0===o.length&&("Enter"===r?await n.sendInputEvent(e,{type:"char",keyCode:"\r"}):1===r.length&&await n.sendInputEvent(e,{type:"char",keyCode:r})),await n.sendInputEvent(e,{type:"keyUp",keyCode:r,modifiers:o}),"Pressed ".concat(t)}let w=new Map;async function f(e){let t=new TextEncoder().encode(e);return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",t))).map(e=>e.toString(16).padStart(2,"0")).join("")}async function g(e){let t;let n=window.bangonit;try{t=await n.capturePage(e)}catch(e){throw Error("could not capture page (page may be navigating)")}let{activeTabId:a}=await n.getTabInfo(e),r="".concat(e,":").concat(null!=a?a:0),i=await f(t);return w.get(r)===i?{type:"not_changed"}:(w.set(r,i),{type:"changed",base64:t})}async function v(e,t){let n=window.bangonit;t.startsWith("http://")||t.startsWith("https://")||(t="https://"+t);let{url:a}=await n.loadURL(e,t);return"Navigated to ".concat(a)}async function x(e){let{ok:t,url:n,reason:a}=await window.bangonit.goBack(e);return t?"Navigated back to ".concat(n):"Cannot go back — ".concat(a)}async function y(e){let{ok:t,url:n,reason:a}=await window.bangonit.goForward(e);return t?"Navigated forward to ".concat(n):"Cannot go forward — ".concat(a)}async function k(e,t){let n=window.bangonit,a=t.action;switch(a){case"list":{let{tabs:t,activeTabId:a}=await n.getTabInfo(e);if(!t.length)return"No tabs open";return t.map(e=>{let t=e.tabId===a?" (active)":"",n=e.isPopup?" (popup)":"";return"Tab ".concat(e.tabId,": ").concat(e.title||"(untitled)"," — ").concat(e.url).concat(t).concat(n)}).join("\n")}case"new":{await n.requestNewTab(e,t.url||"about:blank"),await new Promise(e=>setTimeout(e,3e3));let{activeTabId:a}=await n.getTabInfo(e);return"Opened new tab".concat(t.url?": "+t.url:"",". Active tab is now ").concat(a,".")}case"select":{let a=t.tabId;if(void 0===a)return"Error: tabId required for select";let{tabs:r}=await n.getTabInfo(e);if(!r.find(e=>e.tabId===a))return"Error: tab ".concat(a,' not found. Use browser_tabs with action "list" to see available tabs.');await n.setActiveTab(e,a),await n.requestSelectTab(e,a);let i=r.find(e=>e.tabId===a);return"Switched to tab ".concat(a,": ").concat(null==i?void 0:i.url)}case"close":{var r;let{tabs:a,activeTabId:i}=await n.getTabInfo(e),o=null!==(r=t.tabId)&&void 0!==r?r:i;if(null===o)return"Error: no tab to close";if(!a.find(e=>e.tabId===o))return"Error: tab ".concat(o," not found.");if(a.length<=1)return"Cannot close the last tab.";return await n.requestCloseTab(e,o),"Closed tab ".concat(o)}default:return'Error: unknown tab action "'.concat(a,'". Use list, new, select, or close.')}}async function I(e){let{tabs:t,activeTabId:n}=await window.bangonit.getTabInfo(e);return t.length<=1?"":"\n\nOpen tabs:\n"+t.map(e=>{let t=e.tabId===n?" (active)":"",a=e.isPopup?" (popup)":"";return" Tab ".concat(e.tabId,": ").concat(e.title||"(untitled)"," — ").concat(e.url).concat(t).concat(a)}).join("\n")}async function T(e,t){let n=window.bangonit,a=Math.min(Math.max((null==t?void 0:t.timeout)||10,.1),30),r=null==t?void 0:t.text,i="visible"===((null==t?void 0:t.state)||"visible");if(!r)return await new Promise(e=>setTimeout(e,1e3*a)),"Waited ".concat(a," seconds");let o=Date.now()+1e3*a;for(;Date.now()<o;){let{result:t}=await n.cdpSend(e,"Runtime.evaluate",{expression:"document.body.innerText.includes(".concat(JSON.stringify(r),")"),returnByValue:!0}),a=t.value;if(i&&a)return'Text "'.concat(r,'" is now visible on the page.');if(!i&&!a)return'Text "'.concat(r,'" is no longer visible on the page.');await new Promise(e=>setTimeout(e,500))}return'Timeout: text "'.concat(r,'" ').concat(i?"did not appear":"did not disappear"," within ").concat(a,"s.")}class N{start(){!this.cleanup&&window.bangonit&&(this.cleanup=window.bangonit.onCdpEvent(e=>{"Network.requestWillBeSent"===e.method?this.inflightRequests++:("Network.loadingFinished"===e.method||"Network.loadingFailed"===e.method)&&(this.inflightRequests=Math.max(0,this.inflightRequests-1))}))}stop(){var e;null===(e=this.cleanup)||void 0===e||e.call(this),this.cleanup=null,this.inflightRequests=0}async waitForIdle(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:500,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2e3,n=Date.now()+t,a=0===this.inflightRequests?Date.now():null;for(;Date.now()<n;){if(0===this.inflightRequests){if(a||(a=Date.now()),Date.now()-a>=e)return}else a=null;await new Promise(e=>setTimeout(e,50))}}constructor(){this.inflightRequests=0,this.cleanup=null}}let C={navigate:"browser_navigate",back:"browser_navigate_back",forward:"browser_go_forward",mouse:"browser_mouse",type:"browser_type",press:"browser_press_key",tabs:"browser_tabs",upload:"browser_upload",wait:"browser_wait_for",close:"browser_close"};var j=n(8204);let E=j.VK("type",[j.Ry({type:j.i0("not_changed")}),j.Ry({type:j.i0("changed"),base64:j.Z_()})]);j.Ry({textOutput:j.Z_(),imageOutput:E.nullable()});let S=Promise.resolve();class R{destroy(){this.networkTracker.stop()}enableRecording(e){this.recorder=e}cursorCallbacks(){let e=this.agentId,t=window.bangonit,n=this.recorder;return{onCursorMove:(a,r)=>{t.emitCursorMove(e,a,r),null==n||n.updateCursor(a,r)},onCursorDown:(a,r)=>{t.emitCursorDown(e,a,r),null==n||n.setCursorDown()},onCursorUp:(a,r)=>{t.emitCursorUp(e,a,r),null==n||n.setCursorUp()},onMouseLock:()=>t.emitMouseLock(e),onMouseUnlock:()=>t.emitMouseUnlock(e)}}async callTool(e,t){switch(e){case"browser_navigate":return v(this.agentId,t.url);case"browser_navigate_back":return x(this.agentId);case"browser_go_forward":return y(this.agentId);case"browser_mouse":{let{result:e,mouseX:n,mouseY:a}=await h(this.agentId,t.steps,this.mouseX,this.mouseY,this.cursorCallbacks());return this.mouseX=n,this.mouseY=a,e}case"browser_type":return m(this.agentId,t.text);case"browser_press_key":return b(this.agentId,t.key);case"browser_close":return k(this.agentId,{action:"close"});case"browser_upload":{var n;if(t.cancel){let e=await window.bangonit.handleFileChooser(this.agentId,"cancel");if(!e.ok)return"Error: ".concat(e.error);return"File picker cancelled."}if(!(null===(n=t.paths)||void 0===n?void 0:n.length))return"Error: provide paths to upload, or cancel: true";let e=await window.bangonit.handleFileChooser(this.agentId,"accept",t.paths);if(!e.ok)return"Error: ".concat(e.error);return"Uploaded ".concat(t.paths.length," file(s).")}case"browser_wait_for":return T(this.agentId,t);case"browser_tabs":return k(this.agentId,t);default:throw Error("Unknown tool: ".concat(e))}}async exec(e){let t=function(){let e;let t=new Promise(t=>{e=t}),n=S;return S=S.then(()=>t),{promise:n,release:e}}();await t.promise;try{return await this._exec(e)}finally{t.release()}}async _exec(e){let{actions:t,observe:n}=e,a=[],r=null;if(this.recorder)try{var i,o,l;let e=await (null===(i=window.bangonit)||void 0===i?void 0:i.getTabInfo(this.agentId)),t=null!==(l=null==e?void 0:e.activeTabId)&&void 0!==l?l:0,n=null==e?void 0:null===(o=e.tabs)||void 0===o?void 0:o.find(e=>e.tabId===t);await this.recorder.startClip(t,null==n?void 0:n.url)}catch(e){console.warn("Failed to start recording clip:",e)}for(let e=0;e<t.length;e++){let n=t[e];if(!n||!n.action)continue;let r=C[n.action];if(!r){a.push("".concat(n.action,": Error — unknown action"));continue}try{let e=this.actionToToolArgs(n),t=await this.callTool(r,e);a.push(t||"OK")}catch(e){a.push("".concat(this.actionLabel(n),": Error — ").concat(e.message))}}if(n){t.length>0&&await this.networkTracker.waitForIdle(500,2e3);try{let e=await I(this.agentId),t=await u(this.agentId,this.mouseX,this.mouseY,e);a.push(t),"snapshot_and_screenshot"===n&&(r=await g(this.agentId))}catch(e){a.push("observe: Error — ".concat(e.message))}}if(this.recorder)try{await this.recorder.stopClip()}catch(e){console.warn("Failed to stop recording clip:",e)}return{textOutput:a.join("\n\n"),imageOutput:r}}actionToToolArgs(e){switch(e.action){case"navigate":return{url:e.url};case"back":case"forward":case"close":default:return{};case"mouse":return{steps:(e.mouseActions||[]).map(e=>{if("wait"===e.action)return{action:"wait",ms:e.ms||100};let t=e.ref?{ref:e.ref}:{x:e.x,y:e.y};return"wheel"===e.action?{action:"wheel",...t,dx:e.dx||0,dy:e.dy||0}:{action:e.action,...t}})};case"type":return{text:e.text};case"press":return{key:e.key};case"upload":return{paths:e.paths,cancel:e.cancel};case"tabs":return{action:e.tabAction,tabId:e.tabId,url:e.url};case"wait":return{timeout:e.timeout}}}actionLabel(e){switch(e.action){case"navigate":return"navigate ".concat(e.url);case"mouse":{let t=(e.mouseActions||[]).map(e=>"wait"===e.action?"wait ".concat(e.ms,"ms"):"wheel"===e.action?"wheel ".concat(e.x,",").concat(e.y," ").concat(e.dx,",").concat(e.dy):"".concat(e.action," ").concat(e.x,",").concat(e.y)).join(" → ");return"mouse ".concat(t)}case"type":return'type "'.concat((e.text||"").slice(0,30),'"');case"press":return"press ".concat(e.key);case"upload":return e.cancel?"upload cancel":"upload ".concat((e.paths||[]).join(", "));case"tabs":return"tabs ".concat(e.tabAction).concat(e.tabId?" "+e.tabId:"");case"wait":return"wait ".concat(e.timeout||10,"s");default:return e.action}}constructor(e){this.mouseX=0,this.mouseY=0,this.networkTracker=new N,this.recorder=null,this.agentId=e,this.networkTracker.start()}}class M{async startClip(e,t){this.currentUrl=t||"",this.recording&&await this.cancelClip(),this.recording=!0,this.currentTabId=e,this.currentFrames=[],this.clipStartTime=Date.now();let n=window.bangonit;this.cdpCleanup=n.onCdpEvent(e=>{if(e.agentId!==this.agentId||"Page.screencastFrame"!==e.method||!this.recording)return;let{data:t,metadata:a,sessionId:r}=e.params;this.currentFrames.push({imageData:t,cursor:{...this.cursorPos},clicking:this.clicking,ts:Date.now(),sessionId:r,deviceWidth:(null==a?void 0:a.deviceWidth)||0,deviceHeight:(null==a?void 0:a.deviceHeight)||0,scrollOffsetX:(null==a?void 0:a.scrollOffsetX)||0,scrollOffsetY:(null==a?void 0:a.scrollOffsetY)||0}),n.cdpSend(this.agentId,"Page.screencastFrameAck",{sessionId:r}).catch(e=>console.error(e))}),await n.cdpSend(this.agentId,"Page.startScreencast",{format:"png",quality:100,maxWidth:1920,maxHeight:1080})}async stopClip(){if(!this.recording)return null;this.recording=!1;let e=Date.now();await window.bangonit.cdpSend(this.agentId,"Page.stopScreencast").catch(e=>console.error(e)),this.cdpCleanup&&(this.cdpCleanup(),this.cdpCleanup=null);let t=this.currentFrames;if(this.currentFrames=[],0===t.length)return null;let n=await this.compositeAndEncode(t);if(!n||0===n.size)return null;let a=new Uint8Array(await n.arrayBuffer()),r="";for(let e=0;e<a.length;e++)r+=String.fromCharCode(a[e]);let i=btoa(r),o={agentId:this.agentId,tabId:this.currentTabId,index:this.clips.length,startTime:this.clipStartTime,endTime:e,url:this.currentUrl||void 0,data:i};return this.clips.push(o),{meta:o}}async cancelClip(){var e;this.recording=!1,this.currentFrames=[],this.cdpCleanup&&(this.cdpCleanup(),this.cdpCleanup=null),await (null===(e=window.bangonit)||void 0===e?void 0:e.cdpSend(this.agentId,"Page.stopScreencast").catch(e=>console.error(e)))}async compositeAndEncode(e){if(0===e.length)return null;let t=await this.decodeFrame(e[0].imageData);if(!t)return null;let n=t.width,a=t.height,r=document.createElement("canvas");r.width=n,r.height=a;let i=r.getContext("2d"),o=r.captureStream(0),l=o.getVideoTracks()[0],s=new MediaRecorder(o,{mimeType:"video/webm;codecs=vp8",videoBitsPerSecond:8e6}),c=[];s.ondataavailable=e=>{e.data.size>0&&c.push(e.data)};let u=new Promise(e=>{s.onstop=()=>{e(new Blob(c,{type:"video/webm"}))}});s.start();let d=[];for(let r=0;r<e.length;r++){let o=e[r],s=0===r?t:await this.decodeFrame(o.imageData);if(!s)continue;let c=o.deviceWidth>0?n/o.deviceWidth:1,u=o.deviceHeight>0?a/o.deviceHeight:1,b=o.cursor.x*c,w=o.cursor.y*u;o.clicking&&(0===r||!e[r-1].clicking)&&d.push({x:b,y:w,startTs:o.ts}),i.clearRect(0,0,n,a),i.drawImage(s,0,0,n,a);for(let e=d.length-1;e>=0;e--){var p,h,m;let t=d[e],n=o.ts-t.startTs;if(n>=400){d.splice(e,1);continue}p=t.x,h=t.y,m=n/400,i.save(),i.beginPath(),i.arc(p,h,24*m,0,2*Math.PI),i.fillStyle="rgba(96, 165, 250, ".concat(.8*(1-m),")"),i.fill(),i.restore(),i.save(),i.beginPath(),i.arc(p,h,32*m,0,2*Math.PI),i.strokeStyle="rgba(96, 165, 250, ".concat(.9*(1-m),")"),i.lineWidth=2,i.stroke(),i.restore()}if(!function(e,t,n,a){e.save(),e.translate(t-2,n-1),e.scale(28/24,28/24);let r=new Path2D("M5 3l14 8.5-6.5 1.5-3.5 6z");e.fillStyle="white",e.strokeStyle="black",e.lineWidth=1.5,e.lineJoin="round",e.fill(r),e.stroke(r),e.restore(),a&&(e.save(),e.beginPath(),e.arc(t,n,4,0,2*Math.PI),e.fillStyle="rgba(59, 130, 246, 0.5)",e.fill(),e.restore())}(i,b,w,o.clicking),l&&"function"==typeof l.requestFrame&&l.requestFrame(),r<e.length-1){let t=Math.max(16,Math.min(e[r+1].ts-o.ts,100));await new Promise(e=>setTimeout(e,t))}}return await new Promise(e=>setTimeout(e,100)),s.stop(),u}async decodeFrame(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);let a=new Blob([n],{type:"image/png"});return createImageBitmap(a)}catch(e){return console.warn("Failed to decode frame:",e),null}}updateCursor(e,t){this.cursorPos={x:e,y:t}}setCursorDown(){this.clicking=!0}setCursorUp(){this.clicking=!1}getClipsMeta(){return[...this.clips]}constructor(e){this.clips=[],this.currentFrames=[],this.cursorPos={x:0,y:0},this.clicking=!1,this.recording=!1,this.currentTabId=0,this.clipStartTime=0,this.cdpCleanup=null,this.ripples=[],this.currentUrl="",this.agentId=e}}function z(e){var t;let{agentId:n,agentName:l,initialPrompt:s,onStatusChange:u,onRerun:d,initialMessages:p,initialTabs:h,initialActiveTabId:m,initialTodos:b,record:w,sessionRecorder:f,onRegisterRecorder:g,planDir:v}=e,[x,y]=(0,r.useState)((null==h?void 0:h.map(e=>({...e,initialUrl:e.url})))||[{id:0,url:"about:blank",title:"",initialUrl:"about:blank"}]),[k,I]=(0,r.useState)(null!=m?m:0),[T,N]=(0,r.useState)(()=>{let e=null==h?void 0:h.find(e=>e.id===(null!=m?m:0));return(null==e?void 0:e.url)||""}),[C,j]=(0,r.useState)(null),[E,S]=(0,r.useState)(!1),[z,A]=(0,r.useState)(!1),_=(0,r.useRef)(new Map),[D,O]=(0,r.useState)(b||[]),U=(0,r.useRef)(null),L=(0,r.useRef)(!1),F=(0,r.useRef)(h?Math.max(...h.map(e=>e.id))+1:1),B=(0,r.useRef)(new Set),[H,W]=(0,r.useState)(0),V=(0,r.useRef)(null),J=(0,r.useRef)(null);!J.current&&window.bangonit&&(J.current=new R(n));let X=(0,r.useRef)(null);w&&!X.current&&J.current&&(X.current=new M(n),J.current.enableRecording(X.current),null==g||g(n,X.current));let q=(0,r.useRef)(f);q.current=f;let Y=(0,r.useMemo)(()=>new o.PD({api:"/api/chat",headers:()=>({"X-Client-Platform":navigator.platform})}),[]),G=(0,r.useRef)(!1),K=(0,r.useCallback)((e,t)=>{var a,r;null===(r=window.bangonit)||void 0===r||null===(a=r.emitAgentOutput)||void 0===a||a.call(r,{agentId:n,type:e,text:t,name:l})},[n,l]),{messages:Z,setMessages:Q,sendMessage:$,addToolOutput:ee,stop:et,status:en,error:ea}=(0,i.RJ)({transport:Y,messages:p,sendAutomaticallyWhen:e=>{let{messages:t}=e;return!G.current&&!E&&(0,o.Qk)({messages:t})},async onToolCall(e){var t,a,r,i,o,s,c,u,d;let{toolCall:p}=e;if("report_result"===p.toolName){let e=p.input,u=(null==e?void 0:e.result)==="pass"?"pass":"fail",d=(null==e?void 0:e.summary)||"";if(K("status","".concat(u.toUpperCase(),": ").concat(d)),j({result:u,summary:d}),q.current){q.current.addEvent({ts:Date.now(),agentId:n,type:"result",data:{result:u,summary:d}});try{let e=await (null===(i=window.bangonit)||void 0===i?void 0:null===(r=i.getRunDir)||void 0===r?void 0:r.call(i));if(e){let t=(null===(o=X.current)||void 0===o?void 0:o.getClipsMeta())||[],a=[{id:n,name:l,result:u,summary:d}],r=q.current.toJSON(a,t);await (null===(c=window.bangonit)||void 0===c?void 0:null===(s=c.generateReplayHtml)||void 0===s?void 0:s.call(c,{runDir:e,data:JSON.stringify(r)}))}}catch(e){console.error(e)}}null===(a=window.bangonit)||void 0===a||null===(t=a.reportTestResult)||void 0===t||t.call(a,{agentId:n,status:u,summary:d}),ee({tool:p.toolName,toolCallId:p.toolCallId,output:"Test result recorded: ".concat(u)});return}if("todos"===p.toolName){let e=p.input,t=(null==e?void 0:e.todos)||D;(null==e?void 0:e.todos)&&O(e.todos),ee({tool:p.toolName,toolCallId:p.toolCallId,output:JSON.stringify(t)});return}if("browser"===p.toolName){try{let e=p.input,t=((null==e?void 0:e.actions)||[]).map(e=>"navigate"===e.action?"navigate ".concat(e.url):"type"===e.action?'type "'.concat((e.text||"").slice(0,30),'"'):"press"===e.action?"press ".concat(e.key):"mouse"===e.action?"mouse ".concat((e.mouseActions||[]).map(e=>"".concat(e.action," ").concat(e.ref||"".concat(e.x,",").concat(e.y))).join(" > ")):e.action).join(", ");K("tool","browser: ".concat(t).concat((null==e?void 0:e.observe)?" [".concat(e.observe,"]"):"")),null===(u=q.current)||void 0===u||u.addEvent({ts:Date.now(),agentId:n,type:"tool-start",data:{tool:"browser",label:t}});let a=J.current,r=a?await a.exec({actions:(null==e?void 0:e.actions)||[],observe:null==e?void 0:e.observe,prompts:null==e?void 0:e.prompts}):{error:"Error: browser tools not available"};null===(d=q.current)||void 0===d||d.addEvent({ts:Date.now(),agentId:n,type:"tool-end",data:{tool:"browser"}}),ee({tool:p.toolName,toolCallId:p.toolCallId,output:G.current?{error:"[Stopped by user]"}:JSON.stringify(r)})}catch(e){ee({tool:p.toolName,toolCallId:p.toolCallId,...G.current?{output:"[Stopped by user]"}:{state:"output-error",errorText:e.message}})}return}}});(0,r.useCallback)(()=>{G.current=!0,et()},[et]);let er="submitted"===en||"streaming"===en;(0,r.useEffect)(()=>{er&&(G.current=!1)},[er]);let ei=Z.length>0,eo=null!==C;(0,r.useEffect)(()=>{if(ei&&!V.current&&(V.current=Date.now()),!ei||eo)return;let e=setInterval(()=>{V.current&&W(Math.floor((Date.now()-V.current)/1e3))},1e3);return()=>clearInterval(e)},[ei,eo]);let el=(0,r.useRef)(null),es=(0,r.useRef)(0);(0,r.useEffect)(()=>{var e;if(0===Z.length)return;let t=Z[Z.length-1];if("assistant"!==t.role)return;let n=(null===(e=t.parts)||void 0===e?void 0:e.filter(e=>"text"===e.type).map(e=>e.text).join(""))||"";t.id!==el.current&&(el.current=t.id,es.current=0);let a=n.slice(es.current);a&&(K("text",a),es.current=n.length)},[Z,K]);let ec=(0,r.useRef)(er),eu=(0,r.useRef)(!1);(0,r.useEffect)(()=>{!eu.current&&ec.current!==er&&(ec.current=er,er?null==u||u(n,"running"):(null==u||u(n,"idle",null==C?void 0:C.result),(null==C?void 0:C.result)&&(eu.current=!0)))},[er,n,u,C]);let ed=(0,r.useRef)(!1),ep=(0,r.useRef)(null);(0,r.useEffect)(()=>{if(ep.current&&(clearTimeout(ep.current),ep.current=null),!er&&!eo&&!E&&!ed.current&&!(Z.length<2))return ep.current=setTimeout(()=>{ep.current=null,ed.current||eo||(ed.current=!0,$({text:"You must call the report_result tool to finalize this test run. Call it now with the result (pass or fail) and a summary."}))},5e3),()=>{ep.current&&clearTimeout(ep.current)}},[er,eo,E,Z.length,$]),(0,r.useEffect)(()=>{var e,t;null===(t=window.bangonit)||void 0===t||null===(e=t.clearPartition)||void 0===e||e.call(t,n)},[n]),(0,r.useEffect)(()=>{q.current&&Z.length>0&&q.current.setMessages(n,Z)},[Z,n]),(0,r.useEffect)(()=>{if(Z.length>0){var e,t,a,r;null===(a=window.bangonit)||void 0===a||a.setAgentSession(n,{messages:Z,initialPrompt:s,tabs:x.filter(e=>!e.isPopup).map(e=>{let{id:t,url:n,title:a}=e;return{id:t,url:n,title:a}}),activeTabId:(null===(e=x.find(e=>e.id===k))||void 0===e?void 0:e.isPopup)?null!==(r=null===(t=x.find(e=>!e.isPopup))||void 0===t?void 0:t.id)&&void 0!==r?r:0:k,todos:D})}},[Z,x,k,n,s,D]);let eh=(0,r.useCallback)(e=>{var t;let a=F.current++;y(t=>[...t,{id:a,url:"about:blank",title:"",initialUrl:e}]),I(a),N("about:blank"===e?"":e),null===(t=window.bangonit)||void 0===t||t.setActiveTab(n,a)},[n]),em=(0,r.useCallback)(e=>{y(t=>{let a=t.findIndex(t=>t.id===e);if(-1===a)return t;let r=t.filter(t=>t.id!==e);return 0===r.length?t:(I(t=>{if(t===e){var i;let e=r[Math.max(0,a-1)].id,t=r.find(t=>t.id===e);return t&&N("about:blank"===t.url?"":t.url),null===(i=window.bangonit)||void 0===i||i.setActiveTab(n,e),e}return t}),r)})},[n]),eb=(0,r.useCallback)(e=>{var t;I(e),null===(t=window.bangonit)||void 0===t||t.setActiveTab(n,e),y(t=>{let n=t.find(t=>t.id===e);return n&&N("about:blank"===n.url?"":n.url),t})},[n]),ew=(0,r.useRef)(eh),ef=(0,r.useRef)(em),eg=(0,r.useRef)(eb);ew.current=eh,ef.current=em,eg.current=eb,(0,r.useEffect)(()=>{var e,t,a,r,i;let o=[],l=e=>{e&&o.push(e)};return l(null===(e=window.bangonit)||void 0===e?void 0:e.onTabUpdated(e=>{if(e.agentId!==n)return;let t="about:blank"===e.url,a="about:blank"===e.title;y(n=>n.map(n=>n.id===e.tabId?{...n,...!t&&void 0!==e.url&&{url:e.url},...!a&&void 0!==e.title&&{title:e.title}}:n)),void 0===e.url||t||I(t=>(t===e.tabId&&N(e.url),t))})),l(null===(t=window.bangonit)||void 0===t?void 0:t.onOpenNewTab(e=>{e.agentId===n&&ew.current(e.url)})),l(null===(a=window.bangonit)||void 0===a?void 0:a.onPopupOpened(e=>{e.agentId===n&&y(t=>[...t,{id:e.tabId,url:e.url||"about:blank",title:"",initialUrl:e.url||"about:blank",isPopup:!0}])})),l(null===(r=window.bangonit)||void 0===r?void 0:r.onCloseTab(e=>{e.agentId===n&&ef.current(e.tabId)})),l(null===(i=window.bangonit)||void 0===i?void 0:i.onSelectTab(e=>{e.agentId===n&&eg.current(e.tabId)})),()=>o.forEach(e=>null==e?void 0:e())},[n]),(0,r.useEffect)(()=>{L.current||(null==p?void 0:p.length)||(L.current=!0,$({text:s}))},[s,$,p]),(0,r.useEffect)(()=>{var e;null===(e=U.current)||void 0===e||e.scrollIntoView({behavior:"smooth"})},[Z]);let ev=(0,r.useCallback)((e,t,a)=>{if(!e)return;_.current.set(t,e);let r=()=>{if(!B.current.has(t))try{var r,i,o;let l=null===(r=e.getWebContentsId)||void 0===r?void 0:r.call(e);l&&(B.current.add(t),null===(i=window.bangonit)||void 0===i||i.registerTab(n,t,l,a,v),t===k&&(null===(o=window.bangonit)||void 0===o||o.setActiveTab(n,t)))}catch(e){console.error(e)}};r(),e.addEventListener("did-attach",r),e.addEventListener("close",()=>ef.current(t)),e._consoleListenerAttached||(e._consoleListenerAttached=!0,e.addEventListener("console-message",e=>{var t,a,r;null===(a=window.bangonit)||void 0===a||null===(t=a.emitConsoleMessage)||void 0===t||t.call(a,{agentId:n,level:e.level,message:e.message,url:e.sourceId||"",line:e.lineNumber||0}),null===(r=q.current)||void 0===r||r.addConsoleLog(n,e.level,e.message,e.sourceId||"",e.lineNumber||0)}))},[n,k]),ex=e=>"".concat(Math.floor(e/60),":").concat((e%60).toString().padStart(2,"0"));return(0,a.jsxs)("div",{className:"flex h-full w-full bg-zinc-950 overflow-hidden",children:[(0,a.jsxs)("div",{className:"flex-1 flex flex-col border-r border-zinc-800 min-w-0",children:[(0,a.jsx)("div",{className:"flex items-center bg-zinc-900 border-b border-zinc-800 overflow-x-auto",children:x.map(e=>(0,a.jsx)("button",{onClick:()=>eb(e.id),className:"flex items-center gap-1.5 px-3 py-2 text-xs border-r border-zinc-800 min-w-0 max-w-[200px] shrink-0\n ".concat(e.id===k?"bg-zinc-800 text-zinc-200":"text-zinc-500 hover:text-zinc-300 hover:bg-zinc-850"),children:(0,a.jsxs)("span",{className:"truncate",children:[e.isPopup?"↗ ":"",e.title||(e.url&&"about:blank"!==e.url?e.url:"New Tab")]})},e.id))}),(0,a.jsx)("div",{className:"flex items-center gap-2 px-3 py-2 bg-zinc-900 border-b border-zinc-800",children:(0,a.jsx)("div",{className:"flex-1 px-3 py-1.5 bg-zinc-800 border border-zinc-700 rounded-lg text-xs text-zinc-400 truncate",children:T||"about:blank"})}),(0,a.jsxs)("div",{className:"flex-1 relative bg-white overflow-hidden",onWheel:e=>e.stopPropagation(),children:[x.map(e=>e.isPopup?e.id===k&&(0,a.jsxs)("div",{className:"absolute inset-0 flex items-center justify-center bg-zinc-900 text-zinc-400 text-sm z-[1]",children:["Popup window open — ",e.title||e.url]},e.id):(0,a.jsx)("webview",{ref:t=>ev(t,e.id,e.initialUrl),src:"about:blank",partition:"persist:agent-".concat(n),allowpopups:"",style:{width:"100%",height:"100%",position:"absolute",backgroundColor:"white",top:0,left:0,pointerEvents:e.id===k?"auto":"none",zIndex:e.id===k?1:0}},e.id)),!(null===(t=x.find(e=>e.id===k))||void 0===t?void 0:t.isPopup)&&(0,a.jsx)(c,{agentId:n}),!eo&&(0,a.jsx)("div",{className:"absolute inset-0 z-10 cursor-not-allowed"})]})]}),(0,a.jsxs)("div",{className:"w-[420px] flex flex-col h-full shrink-0",children:[(0,a.jsxs)("div",{className:"flex items-center px-4 py-3 border-b border-zinc-800",children:[(0,a.jsx)("h2",{className:"text-sm font-medium text-zinc-300",children:l}),(0,a.jsx)("div",{className:"flex-1"})]}),C&&(0,a.jsxs)("div",{className:"px-4 py-2 text-sm border-b flex items-center gap-3 ".concat("pass"===C.result?"bg-green-950/30 border-green-900/50":"bg-red-950/30 border-red-900/50"),children:[(0,a.jsx)("span",{className:"font-medium ".concat("pass"===C.result?"text-green-400":"text-red-400"),children:"pass"===C.result?"PASSED":"FAILED"}),(0,a.jsx)("span",{className:"text-zinc-500 text-xs",children:ex(H)}),C.summary&&(0,a.jsx)("span",{className:"text-zinc-400 text-xs truncate flex-1",children:C.summary})]}),D.length>0&&(0,a.jsx)("div",{className:"text-xs space-y-1 px-4 py-2 border-b border-zinc-800 bg-zinc-900/80 shrink-0 max-h-48 overflow-y-auto",children:D.map((e,t)=>(0,a.jsxs)("div",{className:"flex items-center gap-2 ".concat("completed"===e.status?"text-zinc-500":"text-zinc-300"),children:[(0,a.jsx)("span",{className:"shrink-0",children:"completed"===e.status?"✓":"in_progress"===e.status?(0,a.jsx)("span",{className:"inline-block w-2 h-2 bg-blue-500 rounded-full animate-pulse"}):"○"}),(0,a.jsx)("span",{className:"completed"===e.status?"line-through":"",children:e.content})]},t))}),(0,a.jsxs)("div",{className:"flex-1 overflow-y-auto px-4 py-4 space-y-3",children:[Z.map(e=>(0,a.jsx)(P,{message:e,agentName:l},e.id)),ea&&(0,a.jsx)("div",{className:"text-sm px-3 py-2 bg-red-950/30 border border-red-900/50 rounded-lg text-red-400",children:ea.message}),(0,a.jsx)("div",{ref:U})]}),(0,a.jsx)("div",{className:"px-4 py-2 border-t border-zinc-800 flex items-center gap-3 shrink-0",children:eo?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full shrink-0 ".concat("pass"===C.result?"bg-green-500":"bg-red-500")}),(0,a.jsxs)("span",{className:"text-xs font-medium ".concat("pass"===C.result?"text-green-400":"text-red-400"),children:["pass"===C.result?"Passed":"Failed"," in ",ex(H)]}),(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("button",{onClick:()=>{let e=_.current.get(k);e&&(z?e.closeDevTools():e.openDevTools(),A(!z))},className:"text-xs px-2 py-1 rounded border transition-colors ".concat(z?"border-blue-600 text-blue-400 bg-blue-950/30":"border-zinc-700 hover:border-zinc-500 text-zinc-500 hover:text-zinc-300"),title:"Toggle DevTools",children:"DevTools"}),(0,a.jsx)("button",{onClick:()=>{var e,t;null===(t=window.bangonit)||void 0===t||null===(e=t.emitTestRerun)||void 0===e||e.call(t),null==d||d()},className:"text-xs px-3 py-1 rounded border border-zinc-700 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 transition-colors",children:"Rerun"})]}):ei?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full shrink-0 ".concat(E?"bg-amber-500":"bg-blue-500 animate-pulse")}),(0,a.jsxs)("span",{className:"text-xs text-zinc-400",children:[E?"Paused":"Working"," ",ex(H)]}),(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("button",{onClick:()=>{let e=_.current.get(k);e&&(z?e.closeDevTools():e.openDevTools(),A(!z))},className:"text-xs px-2 py-1 rounded border transition-colors ".concat(z?"border-blue-600 text-blue-400 bg-blue-950/30":"border-zinc-700 hover:border-zinc-500 text-zinc-500 hover:text-zinc-300"),title:"Toggle DevTools",children:"DevTools"}),(0,a.jsx)("button",{onClick:()=>S(!E),className:"text-xs px-2 py-1 rounded border border-zinc-700 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 transition-colors",children:E?"Continue":"Pause"})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 bg-zinc-600 rounded-full shrink-0"}),(0,a.jsx)("span",{className:"text-xs text-zinc-500",children:"Queued"})]})})]})]})}function P(e){var t,n;let{message:r,agentName:i}=e;if("user"===r.role){let e=null===(n=r.parts)||void 0===n?void 0:n.find(e=>"text"===e.type);return(0,a.jsxs)("div",{className:"text-sm",children:[(0,a.jsx)("span",{className:"text-xs text-zinc-500 block mb-1",children:"Test Plan"}),(0,a.jsx)("div",{className:"text-zinc-200 prose prose-invert prose-sm max-w-none",children:(0,a.jsx)(l.UG,{remarkPlugins:[s.Z],children:(null==e?void 0:e.text)||""})})]})}return(0,a.jsx)("div",{className:"text-sm space-y-2",children:null===(t=r.parts)||void 0===t?void 0:t.map((e,t)=>{var n,r;if("text"===e.type&&e.text)return(null===(r=e.providerMetadata)||void 0===r?void 0:null===(n=r.anthropic)||void 0===n?void 0:n.type)==="compaction"?null:(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-xs text-zinc-500 block mb-1",children:i}),(0,a.jsx)("div",{className:"text-zinc-300 prose prose-invert prose-sm max-w-none",children:(0,a.jsx)(l.UG,{remarkPlugins:[s.Z],children:e.text})})]},t);if("dynamic-tool"===e.type||"string"==typeof e.type&&e.type.startsWith("tool-")){let n=e.toolName||("string"==typeof e.type?e.type.replace(/^tool-/,""):"");return"todos"===n||"report_result"===n?null:(0,a.jsx)(A,{part:e},t)}return null})})}function A(e){let{part:t}=e,[n,i]=(0,r.useState)(!1),o=t.input||{},l=t.output,s=t.state||"input-available",c=t.toolName||("string"==typeof t.type?t.type.replace(/^tool-/,""):""),u="input-streaming"===s?"":"browser"===c?(()=>{let e=(o.actions||[]).map(e=>{switch(e.action){case"navigate":return"navigate ".concat(e.url||"");case"mouse":{let t=(e.mouseActions||[]).map(e=>"wait"===e.action?"wait ".concat(e.ms,"ms"):"wheel"===e.action?"wheel ".concat(e.ref||"".concat(e.x,",").concat(e.y)):"".concat(e.action," ").concat(e.ref||"".concat(e.x,",").concat(e.y))).join(" → ");return"mouse ".concat(t)}case"type":return'type "'.concat((e.text||"").slice(0,40),'"');case"press":return"press ".concat(e.key||"");case"tabs":return"tabs ".concat(e.tabAction||"").concat(e.tabId?" "+e.tabId:"");default:return e.action||""}});return o.observe&&e.push(o.observe),e.join(", ")})():o.command||(Object.keys(o).length>0?JSON.stringify(o):"");return(0,a.jsxs)("div",{className:"text-sm",children:[(0,a.jsxs)("button",{onClick:()=>i(!n),className:"flex items-center gap-2 text-xs px-2 py-1.5 bg-zinc-900 border border-zinc-800 rounded-lg hover:border-zinc-700 transition-colors w-full text-left min-w-0",children:["input-streaming"===s||"input-available"===s?(0,a.jsx)("span",{className:"inline-block w-2 h-2 bg-amber-500 rounded-full animate-pulse shrink-0"}):(0,a.jsx)("span",{className:"text-green-500 shrink-0",children:"✓"}),(0,a.jsx)("span",{className:"text-zinc-400 font-mono truncate",children:u}),(0,a.jsx)("span",{className:"ml-auto transition-transform text-zinc-600 shrink-0 ".concat(n?"rotate-90":""),children:"▶"})]}),n&&(0,a.jsxs)("pre",{className:"mt-1 px-3 py-2 bg-zinc-900/50 rounded-lg border border-zinc-800 text-xs whitespace-pre-wrap overflow-x-auto max-h-60 overflow-y-auto",children:[u&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("span",{className:"text-zinc-300 select-all",children:["$ ",u]}),"\n"]}),null!=l&&(()=>{if("browser"===c&&"string"==typeof l)try{let e=JSON.parse(l);if(void 0!==e.textOutput)return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-zinc-500",children:e.textOutput}),e.imageOutput&&(0,a.jsxs)(a.Fragment,{children:["\n",(0,a.jsx)("span",{className:"changed"===e.imageOutput.type?"text-blue-400":"text-zinc-600",children:"changed"===e.imageOutput.type?"[screenshot: changed]":"[screenshot: unchanged]"})]})]})}catch(e){console.error(e)}return(0,a.jsx)("span",{className:"text-zinc-500",children:"string"==typeof l?l:JSON.stringify(l,null,2)})})()]})]})}let _={0:"debug",1:"log",2:"warn",3:"error"};class D{addEvent(e){this.events.push(e)}setMessages(e,t){let n=Date.now(),a=JSON.parse(JSON.stringify(t));for(let t=0;t<a.length;t++){let r=a[t],i="".concat(e,":").concat(t);if(this.seenParts.has(i)||this.seenParts.set(i,n),r._ts=this.seenParts.get(i),r.parts)for(let a=0;a<r.parts.length;a++){let i="".concat(e,":").concat(t,":").concat(a);this.seenParts.has(i)||this.seenParts.set(i,n),r.parts[a]._ts=this.seenParts.get(i)}}this.messages.set(e,a)}addConsoleLog(e,t,n,a,r){this.consoleLogs.has(e)||this.consoleLogs.set(e,[]),this.consoleLogs.get(e).push({ts:Date.now(),level:_[t]||"log",message:n,url:a,line:r})}toJSON(e,t){return{runId:this.runId,startTime:this.startTime,endTime:Date.now(),agents:e,timeline:[...this.events].sort((e,t)=>e.ts-t.ts),messages:Object.fromEntries(this.messages),consoleLogs:Object.fromEntries(this.consoleLogs),clips:t}}constructor(e){this.events=[],this.messages=new Map,this.consoleLogs=new Map,this.seenParts=new Map,this.runId=e,this.startTime=Date.now()}}function O(){let[e,t]=(0,r.useState)([]),[n,i]=(0,r.useState)({}),[o,l]=(0,r.useState)({}),[s,c]=(0,r.useState)(!1),[u,d]=(0,r.useState)({}),p=(0,r.useRef)(new Map),[h,m]=(0,r.useState)(null),[b,w]=(0,r.useState)(!1),[f,g]=(0,r.useState)(!1),v=(0,r.useRef)(null),x=(0,r.useRef)(new Map);(0,r.useEffect)(()=>{(async()=>{var e,n,a,r,o;let s=await (null===(e=window.bangonit)||void 0===e?void 0:e.getAgents())||[];if(0===s.length){let e={id:crypto.randomUUID(),name:"Test 1",createdAt:Date.now()};s.push(e),await (null===(a=window.bangonit)||void 0===a?void 0:a.setAgents(s))}t(s);let u={},d={};for(let e of s){let t=await (null===(r=window.bangonit)||void 0===r?void 0:r.getAgentSession(e.id));t&&(null===(o=t.messages)||void 0===o?void 0:o.length)>0&&(u[e.id]={initialPrompt:t.initialPrompt,initialMessages:t.messages.map(e=>{if("assistant"!==e.role||!e.parts)return e;let t=e.parts.map(e=>"tool-invocation"===e.type&&"result"!==e.state?{...e,state:"result",output:"[Interrupted — app was restarted]"}:e);return{...e,parts:t}}),initialTabs:t.tabs,initialActiveTabId:t.activeTabId,initialTodos:t.todos},d[e.id]="idle")}l(u),i(d),m((null===(n=s[0])||void 0===n?void 0:n.id)||null),c(!0)})()},[]);let y=(0,r.useRef)(e);y.current=e,(0,r.useEffect)(()=>{if(s&&e.length>0){var t;null===(t=window.bangonit)||void 0===t||t.setAgents(e)}},[e,s]);let k=(0,r.useCallback)(async e=>{var t,n;await (null===(n=window.bangonit)||void 0===n?void 0:null===(t=n.clearPartition)||void 0===t?void 0:t.call(n,e));let a=o[e];a&&(i(t=>({...t,[e]:"running"})),d(t=>({...t,[e]:(t[e]||0)+1})),l(t=>({...t,[e]:{initialPrompt:a.initialPrompt}})))},[o]),I=(0,r.useCallback)((e,t)=>{x.current.set(e,t)},[]),T=(0,r.useRef)(n);T.current=n;let N=(0,r.useCallback)(async(e,t)=>{var n,a,r,i;let o=v.current;if(!o)return;let l=await (null===(a=window.bangonit)||void 0===a?void 0:null===(n=a.getRunDir)||void 0===n?void 0:n.call(a));if(!l)return;let s=[];for(let e of x.current.values())s.push(...e.getClipsMeta());let c={...T.current,[e]:t},u=y.current.map(e=>{let t=c[e.id];return{id:e.id,name:e.name,result:"completed"===t?"pass":"failed"===t?"fail":void 0}}),d=o.toJSON(u,s);await (null===(i=window.bangonit)||void 0===i?void 0:null===(r=i.generateReplayHtml)||void 0===r?void 0:r.call(i,{runDir:l,data:JSON.stringify(d)}))},[]),C=(0,r.useCallback)((e,t,n)=>{let a;if(a="running"===t?"running":"pass"===n?"completed":"fail"===n?"failed":"idle",i(t=>({...t,[e]:a})),b&&("pass"===n||"fail"===n)&&N(e,a),"fail"===n){let t=p.current.get(e);if(t&&t.attempt<t.maxRetries){var r,o;t.attempt++,null===(o=window.bangonit)||void 0===o||null===(r=o.emitTestRetry)||void 0===r||r.call(o,{agentId:e,attempt:t.attempt,maxRetries:t.maxRetries}),setTimeout(()=>k(e),1e3)}}},[k,b,N]),j=(0,r.useCallback)((e,n,a)=>{a&&t(t=>t.map(t=>t.id===e?{...t,name:a}:t)),l(t=>({...t,[e]:{initialPrompt:n}})),i(t=>({...t,[e]:"running"})),m(e)},[]),E=(0,r.useCallback)(()=>{let n=crypto.randomUUID(),a={id:n,name:"Test ".concat(e.length+1),createdAt:Date.now()};t(e=>[...e,a]),m(n)},[e.length]);if((0,r.useEffect)(()=>{var e,n;let a=null===(n=window.bangonit)||void 0===n?void 0:null===(e=n.onTestPlan)||void 0===e?void 0:e.call(n,e=>{g(!0);let{agentIndex:n,testPlan:a,name:r,retries:o,extraPrompt:s,record:c,planDir:u}=e;if(c&&!v.current){let e=new Date().toISOString().replace(/[:.]/g,"-");v.current=new D(e),w(!0)}t(e=>{let t=n+1,a=[...e];for(;a.length<t;)a.push({id:crypto.randomUUID(),name:r||"Test ".concat(a.length+1),createdAt:Date.now()});return r&&(a=a.map((e,t)=>t===n?{...e,name:r}:e)),a}),setTimeout(()=>{t(e=>{let t=e[n];if(!t)return e;let r=s?"".concat(a,"\n\n## Additional Instructions\n").concat(s):a;return l(e=>({...e,[t.id]:{initialPrompt:r,planDir:u}})),i(e=>({...e,[t.id]:"running"})),o&&o>0&&p.current.set(t.id,{maxRetries:o,attempt:0,testPlan:r}),0===n&&m(t.id),e})},100)});return()=>null==a?void 0:a()},[]),(0,r.useEffect)(()=>{var e,t;let n=null===(t=window.bangonit)||void 0===t?void 0:null===(e=t.onFocusAgent)||void 0===e?void 0:e.call(t,e=>{m(e.agentId)});return()=>null==n?void 0:n()},[]),!s)return(0,a.jsx)("div",{className:"flex h-screen bg-zinc-950"});e.some(e=>o[e.id]);let S=e.find(e=>e.id===h),R=!!h&&!!o[h];return(0,a.jsxs)("div",{className:"flex h-screen bg-zinc-950 overflow-hidden",children:[(0,a.jsxs)("div",{className:"flex flex-col bg-zinc-900 border-r border-zinc-800 shrink-0 w-48 overflow-y-auto",children:[(0,a.jsxs)("div",{className:"flex items-center px-3 py-2 border-b border-zinc-800",children:[(0,a.jsx)("span",{className:"text-xs font-medium text-zinc-500 uppercase tracking-wider",children:"Tests"}),(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("button",{onClick:E,className:"text-zinc-500 hover:text-zinc-300 transition-colors text-lg leading-none",title:"Add test",children:"+"})]}),e.map(e=>{let t=n[e.id];return o[e.id],(0,a.jsx)("button",{onClick:()=>m(e.id),className:"px-3 py-2 text-xs text-left border-b border-zinc-800 transition-colors\n ".concat(e.id===h?"bg-zinc-800 text-zinc-200":"text-zinc-500 hover:text-zinc-300"),children:(0,a.jsxs)("span",{className:"flex items-center gap-2",children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full shrink-0 ".concat("running"===t?"bg-blue-500 animate-pulse":"completed"===t?"bg-green-500":"failed"===t?"bg-red-500":"bg-zinc-600")}),(0,a.jsx)("span",{className:"truncate",children:e.name})]})},e.id)})]}),(0,a.jsxs)("div",{className:"flex-1 min-w-0 h-full relative",children:[e.map(e=>o[e.id]?(0,a.jsx)("div",{className:"absolute inset-0 z-0",style:{display:"flex",zIndex:e.id===h?1:0,pointerEvents:e.id===h?"auto":"none"},children:(0,a.jsx)(z,{agentId:e.id,agentName:e.name,initialPrompt:o[e.id].initialPrompt,initialMessages:o[e.id].initialMessages,initialTabs:o[e.id].initialTabs,initialActiveTabId:o[e.id].initialActiveTabId,initialTodos:o[e.id].initialTodos,onStatusChange:C,onRerun:()=>k(e.id),record:b,sessionRecorder:v.current||void 0,onRegisterRecorder:I,planDir:o[e.id].planDir})},"".concat(e.id,"-").concat(u[e.id]||0)):null),S&&!R&&!f&&(0,a.jsx)(U,{agentId:S.id,agentName:S.name,onSubmit:j})]})]})}function U(e){let{agentId:t,agentName:n,onSubmit:i}=e,[o,l]=(0,r.useState)(""),s=(0,r.useRef)(null);(0,r.useEffect)(()=>{var e;null===(e=s.current)||void 0===e||e.focus()},[t]);let c=()=>{let e=o.trim();e&&i(t,e)};return(0,a.jsx)("div",{className:"absolute inset-0 flex items-center justify-center z-10 bg-zinc-950",children:(0,a.jsxs)("div",{className:"w-full max-w-xl px-6",children:[(0,a.jsx)("h2",{className:"text-lg font-medium text-zinc-200 mb-4",children:"What would you like to test?"}),(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)("textarea",{ref:s,value:o,onChange:e=>l(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),c())},placeholder:"Describe what to test in plain English...",className:"w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-sm text-zinc-200 placeholder-zinc-500 resize-none focus:outline-none focus:border-zinc-500 transition-colors",rows:4}),(0,a.jsx)("button",{onClick:c,disabled:!o.trim(),className:"absolute bottom-3 right-3 px-3 py-1.5 bg-blue-600 hover:bg-blue-500 disabled:bg-zinc-700 disabled:text-zinc-500 text-white text-xs font-medium rounded transition-colors",children:"Run"})]}),(0,a.jsx)("p",{className:"text-xs text-zinc-600 mt-2",children:"Press Enter to run. Shift+Enter for a new line."}),(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsx)("p",{className:"text-xs text-zinc-600 mb-2",children:"Examples:"}),(0,a.jsx)("div",{className:"flex flex-col gap-1.5",children:["Go to example.com and verify the homepage loads with a heading","Navigate to my-app.com/login, sign in with test@example.com / password123, and verify the dashboard loads","Go to localhost:3000, add an item to the cart, proceed to checkout, and verify the order summary"].map((e,t)=>(0,a.jsx)("button",{onClick:()=>l(e),className:"text-left text-xs text-zinc-500 hover:text-zinc-300 bg-zinc-900 hover:bg-zinc-800 px-3 py-2 rounded border border-zinc-800 transition-colors",children:e},t))})]})]})})}function L(){return(0,a.jsx)(O,{})}}},function(e){e.O(0,[46,631,293,528,744],function(){return e(e.s=6421)}),_N_E=e.O()}]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bangonit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "AI-powered E2E testing tool",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bangonit": "bin/src/cli/bangonit.js",
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"prepublishOnly": "npm run build",
|
|
12
|
-
"build": "npm
|
|
13
|
-
"build:cli": "npx tsc -p tsconfig.cli.json",
|
|
12
|
+
"build": "concurrently npm:build:cli npm:build:webapp npm:build:electron npm:build:replay",
|
|
13
|
+
"build:cli": "rm -fr bin && npx tsc -p tsconfig.cli.json && chmod +x bin/src/cli/bangonit.js",
|
|
14
14
|
"build:webapp": "cd app/webapp && npm run build && cp -r .next/static .next/standalone/app/webapp/.next/static",
|
|
15
15
|
"build:electron": "cd app/desktopapp && npx tsc",
|
|
16
|
-
"build:replay": "cd app/replay && npx vite build"
|
|
16
|
+
"build:replay": "cd app/replay && npx vite build",
|
|
17
|
+
"test": "node --test test/*.test.ts"
|
|
17
18
|
},
|
|
18
19
|
"workspaces": [
|
|
19
20
|
"app/*"
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
51
52
|
"@iarna/toml": "^2.2.5",
|
|
53
|
+
"dotenv": "^17.3.1",
|
|
52
54
|
"electron": "^40.8.0",
|
|
53
55
|
"electron-store": "^8.1.0",
|
|
54
56
|
"is-ci": "^4.1.0",
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
"devDependencies": {
|
|
60
62
|
"@types/is-ci": "^3.0.4",
|
|
61
63
|
"@types/yargs": "^17.0.35",
|
|
64
|
+
"concurrently": "^9.2.1",
|
|
62
65
|
"playwright": "^1.58.2"
|
|
63
66
|
}
|
|
64
67
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[191],{6421:function(e,t,n){Promise.resolve().then(n.bind(n,2953))},2953:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return L}});var a=n(7573),r=n(7653),i=n(774),o=n(1446),l=n(2574),s=n(3334);function c(e){let{agentId:t}=e,[n,i]=(0,r.useState)(null),[o,l]=(0,r.useState)(!1),[s,c]=(0,r.useState)(!1),[u,d]=(0,r.useState)([]),p=(0,r.useRef)(),h=(0,r.useRef)(0),m=(0,r.useCallback)(()=>{l(!0),clearTimeout(p.current),p.current=setTimeout(()=>l(!1),2e3)},[]);return((0,r.useEffect)(()=>{var e,n,a;let r=[];return r.push(null===(e=window.bangonit)||void 0===e?void 0:e.onCursorMove(e=>{e.agentId===t&&(i({x:e.x,y:e.y}),m())})),r.push(null===(n=window.bangonit)||void 0===n?void 0:n.onCursorDown(e=>{if(e.agentId!==t)return;i({x:e.x,y:e.y}),c(!0),m();let n=++h.current;d(t=>[...t,{id:n,x:e.x,y:e.y}]),setTimeout(()=>{d(e=>e.filter(e=>e.id!==n))},400)})),r.push(null===(a=window.bangonit)||void 0===a?void 0:a.onCursorUp(e=>{e.agentId===t&&(c(!1),m())})),()=>{r.forEach(e=>null==e?void 0:e()),clearTimeout(p.current)}},[t,m]),n)?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("svg",{width:"28",height:"28",viewBox:"0 0 24 24",className:"pointer-events-none absolute z-20",style:{left:n.x,top:n.y,transform:"translate(-2px, -1px) ".concat(s?"scale(0.8)":"scale(1)"),transition:"left 30ms linear, top 30ms linear, transform 80ms ease-out, opacity 400ms ease-out",opacity:o?1:0,filter:"drop-shadow(0 1px 2px rgba(0,0,0,0.5))"},children:(0,a.jsx)("path",{d:"M5 3l14 8.5-6.5 1.5-3.5 6z",fill:"white",stroke:"black",strokeWidth:"1.5",strokeLinejoin:"round"})}),u.map(e=>(0,a.jsxs)("span",{children:[(0,a.jsx)("span",{className:"pointer-events-none absolute z-20 rounded-full bg-blue-400/50",style:{left:e.x,top:e.y,width:0,height:0,transform:"translate(-50%, -50%)",animation:"cursor-ripple ".concat(400,"ms ease-out forwards")}}),(0,a.jsx)("span",{className:"pointer-events-none absolute z-20 rounded-full border-2 border-blue-400/60",style:{left:e.x,top:e.y,width:0,height:0,transform:"translate(-50%, -50%)",animation:"cursor-ripple-ring ".concat(400,"ms ease-out forwards")}})]},e.id)),(0,a.jsx)("style",{children:"\n @keyframes cursor-ripple {\n 0% { width: 0; height: 0; opacity: 0.8; }\n 100% { width: 48px; height: 48px; opacity: 0; }\n }\n @keyframes cursor-ripple-ring {\n 0% { width: 0; height: 0; opacity: 0.9; }\n 100% { width: 64px; height: 64px; opacity: 0; }\n }\n "})]}):null}async function u(e,t,n,a){let[{result:r},i,o,{result:l}]=await Promise.all([window.bangonit.cdpSend(e,"Runtime.evaluate",{expression:"\n(function() {\n var MAX_CHARS = 60000;\n var MAX_ELEMENTS = 5000;\n var MAX_DEPTH = 1500;\n var totalChars = 0;\n var visited = 0;\n var truncated = false;\n var refCounter = 0;\n\n window.__dmjRefs = new Map();\n\n var SKIP_TAGS = {SCRIPT:1,STYLE:1,NOSCRIPT:1,SVG:1,PATH:1,META:1,LINK:1,TEMPLATE:1,IFRAME:1,BR:1,HR:1,WBR:1,CANVAS:1,VIDEO:1,AUDIO:1,MAP:1,AREA:1,PICTURE:1,SOURCE:1,TRACK:1,OBJECT:1,EMBED:1};\n var INTERACTIVE_ROLES = {button:1,link:1,textbox:1,checkbox:1,radio:1,combobox:1,menuitem:1,tab:1,switch:1,option:1};\n var INPUT_ROLE = {checkbox:'checkbox',radio:'radio',submit:'button',button:'button',search:'searchbox',file:'file'};\n var TAG_ROLE = {A:'link',BUTTON:'button',SELECT:'combobox',TEXTAREA:'textbox',IMG:'img',H1:'heading',H2:'heading',H3:'heading',H4:'heading',H5:'heading',H6:'heading',NAV:'navigation',MAIN:'main',FORM:'form',TABLE:'table',UL:'list',OL:'list',LI:'listitem'};\n\n function isVisible(el) {\n if (el.hidden || el.getAttribute('aria-hidden') === 'true') return false;\n if (!el.offsetParent && el.tagName !== 'BODY' && el.tagName !== 'HTML') {\n var pos = getComputedStyle(el).position;\n if (pos !== 'fixed' && pos !== 'sticky') return false;\n }\n var s = el.style;\n if (s.display === 'none' || s.visibility === 'hidden') return false;\n return true;\n }\n\n function isInteractive(el) {\n var tag = el.tagName;\n if (tag === 'A' || tag === 'BUTTON' || tag === 'SELECT' || tag === 'TEXTAREA') return true;\n if (tag === 'INPUT' && el.type !== 'hidden') return true;\n var role = el.getAttribute('role');\n if (role && INTERACTIVE_ROLES[role]) return true;\n var tabindex = el.getAttribute('tabindex');\n if (el.onclick || (tabindex !== null && tabindex >= '0')) return true;\n if (el.contentEditable === 'true') return true;\n return false;\n }\n\n function getRole(el) {\n var r = el.getAttribute('role');\n if (r) return r;\n if (el.tagName === 'INPUT') return INPUT_ROLE[(el.type||'text').toLowerCase()] || 'textbox';\n return TAG_ROLE[el.tagName] || null;\n }\n\n function getLabel(el) {\n return (el.getAttribute('aria-label') || el.getAttribute('placeholder') || el.getAttribute('alt') || el.getAttribute('title') || '').slice(0, 50);\n }\n\n function directText(el) {\n var t = '';\n for (var n = el.firstChild; n; n = n.nextSibling) {\n if (n.nodeType === 3) t += n.data;\n if (t.length > 60) break;\n }\n return t.trim().replace(/\\s+/g, ' ').slice(0, 60);\n }\n\n function walk(el, depth) {\n if (truncated || !el || el.nodeType !== 1) return '';\n if (SKIP_TAGS[el.tagName]) return '';\n if (!isVisible(el)) return '';\n if (depth > MAX_DEPTH) return '';\n if (++visited > MAX_ELEMENTS) { truncated = true; return ''; }\n\n var role = getRole(el);\n var interactive = isInteractive(el);\n var showThis = !!(role || interactive);\n var lines = [];\n\n if (showThis) {\n var label = getLabel(el);\n var dtext = directText(el);\n var line = '[' + (role || el.tagName.toLowerCase());\n var txt = label || dtext;\n if (txt) line += ' \"' + txt.replace(/\"/g, \"'\") + '\"';\n if (interactive) {\n var ref = 'e' + (++refCounter);\n window.__dmjRefs.set(ref, new WeakRef(el));\n line += ' ref=' + ref;\n }\n line += ']';\n if (el === document.activeElement) line += ' [focused]';\n if ((el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') && el.value) line += ' val=\"' + el.value.slice(0,40) + '\"';\n if (el.tagName === 'INPUT' && (el.type === 'checkbox' || el.type === 'radio')) line += el.checked ? ' [x]' : ' [ ]';\n\n totalChars += line.length;\n if (totalChars > MAX_CHARS) { truncated = true; return ''; }\n lines.push(line);\n }\n\n for (var c = el.firstElementChild; c; c = c.nextElementSibling) {\n if (truncated) break;\n var out = walk(c, showThis ? depth + 1 : depth);\n if (out) lines.push(showThis ? out.split('\\n').map(function(l){return ' '+l}).join('\\n') : out);\n }\n\n if (!showThis) {\n var dt = directText(el);\n if (dt.length > 2) {\n totalChars += dt.length;\n if (totalChars > MAX_CHARS) { truncated = true; return ''; }\n lines.push('\"' + dt + '\"');\n }\n }\n\n return lines.join('\\n');\n }\n\n var tree = walk(document.body, 0);\n var h = 'URL: ' + location.href + '\\nTitle: ' + document.title;\n if (truncated) h += '\\n[TRUNCATED - page too large]';\n return h + '\\n\\n' + tree;\n})()\n",returnByValue:!0}),window.bangonit.getDownloads(e),window.bangonit.getFileChooserState(e),window.bangonit.cdpSend(e,"Runtime.evaluate",{expression:"JSON.stringify({w:window.innerWidth,h:window.innerHeight})",returnByValue:!0})]),s=(()=>{try{return JSON.parse(l.value)}catch(e){return null}})(),c=s?"\nViewport: ".concat(s.w,"x").concat(s.h):"",u=(r.value||"Empty page")+"\n\nMouse position: ".concat(t,",").concat(n).concat(c)+a;if(o.open&&(u+="\n\n[File picker is open — use upload action with paths to select files, or cancel: true to dismiss]"),i.length>0){let e=i.map(e=>"- ".concat(e.filename," (").concat(e.bytes," bytes) [").concat(e.state,"]"));u+="\n\nDownloads:\n".concat(e.join("\n"))}return u}async function d(e,t,n){let a=window.bangonit;if(t.ref){let{result:i}=await a.cdpSend(e,"Runtime.evaluate",{expression:'(function() { var r = window.__dmjRefs && window.__dmjRefs.get("'.concat(t.ref,'"); return r ? r.deref() || null : null; })()'),returnByValue:!1});if(!i.objectId)throw Error('Element ref "'.concat(t.ref,'" not found — take a new snapshot'));try{let{model:r}=await a.cdpSend(e,"DOM.getBoxModel",{objectId:i.objectId}),o=r.content,l=Math.round((o[0]+o[2]+o[4]+o[6])/4),s=Math.round((o[1]+o[3]+o[5]+o[7])/4);if(n){let{result:t}=await a.cdpSend(e,"Runtime.evaluate",{expression:"JSON.stringify({ w: window.innerWidth, h: window.innerHeight })",returnByValue:!0}),n=JSON.parse(t.value);if(l<0||l>n.w||s<0||s>n.h){await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:'function() { this.scrollIntoView({ block: "center", inline: "center", behavior: "instant" }); }',returnByValue:!0}),await new Promise(e=>setTimeout(e,100));let{model:t}=await a.cdpSend(e,"DOM.getBoxModel",{objectId:i.objectId}),n=t.content;l=Math.round((n[0]+n[2]+n[4]+n[6])/4),s=Math.round((n[1]+n[3]+n[5]+n[7])/4)}}else if(l<0||s<0){let{result:n}=await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:"function() {\n var r = this.getBoundingClientRect();\n return { top: r.top, bottom: r.bottom, left: r.left, right: r.right, vh: window.innerHeight, vw: window.innerWidth };\n }",returnByValue:!0}),r=n.value;if(r){let e=r.top<0?Math.round(r.top-100):r.bottom>r.vh?Math.round(r.bottom-r.vh+100):0,n=0!==e?" Scroll ".concat(e>0?"down":"up"," ~").concat(Math.abs(e),"px (wheel dy=").concat(e," at current mouse position)"):"";throw Error('Element ref "'.concat(t.ref,'" is not in the viewport and cannot auto-scroll because this batch contains x,y coordinates that would be invalidated by scrolling.').concat(n))}}return{x:l,y:s}}catch(o){var r;if(null===(r=o.message)||void 0===r?void 0:r.includes("not in the viewport"))throw o;if(n)try{await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:'function() { this.scrollIntoView({ block: "center", inline: "center", behavior: "instant" }); }',returnByValue:!0}),await new Promise(e=>setTimeout(e,100));let{model:t}=await a.cdpSend(e,"DOM.getBoxModel",{objectId:i.objectId}),n=t.content;return{x:Math.round((n[0]+n[2]+n[4]+n[6])/4),y:Math.round((n[1]+n[3]+n[5]+n[7])/4)}}catch(e){throw Error('Element ref "'.concat(t.ref,'" could not be scrolled into view'))}try{let{result:n}=await a.cdpSend(e,"Runtime.callFunctionOn",{objectId:i.objectId,functionDeclaration:"function() {\n var r = this.getBoundingClientRect();\n return { top: r.top, bottom: r.bottom, left: r.left, right: r.right, vh: window.innerHeight, vw: window.innerWidth };\n }",returnByValue:!0}),r=n.value;if(r){let e=r.top<0?Math.round(r.top-100):r.bottom>r.vh?Math.round(r.bottom-r.vh+100):0,n=0!==e?" Scroll ".concat(e>0?"down":"up"," ~").concat(Math.abs(e),"px (wheel dy=").concat(e," at current mouse position)"):"";throw Error('Element ref "'.concat(t.ref,'" is not in the viewport and cannot auto-scroll because this batch contains x,y coordinates that would be invalidated by scrolling.').concat(n))}}catch(e){if(e.message.includes("not in the viewport"))throw e}throw Error('Element ref "'.concat(t.ref,'" is not visible in the viewport — use only refs or scroll manually first'))}finally{a.cdpSend(e,"Runtime.releaseObject",{objectId:i.objectId}).catch(e=>console.error(e))}}return{x:t.x,y:t.y}}async function p(e,t,n,a,r,i){let o=window.bangonit,l=Math.hypot(a-t,r-n);if(l<1){null==i||i(a,r);return}let s=Math.min(Math.max(Math.round(l/15),3),40),c=Math.min(Math.max(.8*l,30),300);for(let l=1;l<=s;l++){let u=l/s,d=u<.5?4*u*u*u:1-Math.pow(-2*u+2,3)/2,p=Math.round(t+(a-t)*d),h=Math.round(n+(r-n)*d);await o.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseMoved",x:p,y:h}),null==i||i(p,h),l<s&&await new Promise(e=>setTimeout(e,c/s))}}async function h(e,t,n,a,r){var i,o,l,s,c,u,h,m;let b=window.bangonit;null===(i=r.onMouseLock)||void 0===i||i.call(r);let w=!t.some(e=>"wait"!==e.action&&void 0!==e.x),f=n,g=a;try{let n=[];for(let a of t){if("wait"===a.action){await new Promise(e=>setTimeout(e,Math.min(a.ms||100,2e3))),n.push("wait(".concat(a.ms||100,"ms)"));continue}let t=a.ref?{ref:a.ref}:{x:a.x,y:a.y},i=await d(e,t,w),m="".concat(i.x,",").concat(i.y),{x:v,y:x}=i;switch(a.action){case"down":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,null===(o=r.onCursorDown)||void 0===o||o.call(r,v,x),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:1}),n.push("down(".concat(m,")"));break;case"move":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,n.push("move(".concat(m,")"));break;case"up":await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:1}),null===(l=r.onCursorUp)||void 0===l||l.call(r,v,x),n.push("up(".concat(m,")"));break;case"click":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,null===(s=r.onCursorDown)||void 0===s||s.call(r,v,x),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:1}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:1}),null===(c=r.onCursorUp)||void 0===c||c.call(r,v,x),n.push("click(".concat(m,")"));break;case"dblclick":await p(e,f,g,v,x,r.onCursorMove),f=v,g=x,null===(u=r.onCursorDown)||void 0===u||u.call(r,v,x),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:1}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:1}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mousePressed",x:v,y:x,button:"left",clickCount:2}),await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseReleased",x:v,y:x,button:"left",clickCount:2}),null===(h=r.onCursorUp)||void 0===h||h.call(r,v,x),n.push("dblclick(".concat(m,")"));break;case"wheel":{await p(e,f,g,v,x,r.onCursorMove),f=v,g=x;let t=a.dx||0,i=a.dy||0;await b.cdpSend(e,"Input.dispatchMouseEvent",{type:"mouseWheel",x:v,y:x,deltaX:t,deltaY:i}),n.push("wheel(".concat(m,",").concat(t,",").concat(i,")"))}}}return{result:"Mouse: ".concat(n.join(" → ")),mouseX:f,mouseY:g}}finally{null===(m=r.onMouseUnlock)||void 0===m||m.call(r)}}async function m(e,t){let n=window.bangonit;for(let a of t)await n.sendInputEvent(e,{type:"keyDown",keyCode:a}),await n.sendInputEvent(e,{type:"char",keyCode:a}),await n.sendInputEvent(e,{type:"keyUp",keyCode:a}),await new Promise(e=>setTimeout(e,30+70*Math.random()));return'Typed "'.concat(t.slice(0,50),'"')}async function b(e,t){let n=window.bangonit,a=t.split("+"),r=a.pop(),i=a.map(e=>e.toLowerCase()),o=[];for(let e of i)"control"===e||"ctrl"===e?o.push("control"):"meta"===e||"command"===e||"cmd"===e?o.push("meta"):"alt"===e||"option"===e?o.push("alt"):"shift"===e&&o.push("shift");return await n.sendInputEvent(e,{type:"keyDown",keyCode:r,modifiers:o}),0===o.length&&("Enter"===r?await n.sendInputEvent(e,{type:"char",keyCode:"\r"}):1===r.length&&await n.sendInputEvent(e,{type:"char",keyCode:r})),await n.sendInputEvent(e,{type:"keyUp",keyCode:r,modifiers:o}),"Pressed ".concat(t)}let w=new Map;async function f(e){let t=new TextEncoder().encode(e);return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256",t))).map(e=>e.toString(16).padStart(2,"0")).join("")}async function g(e){let t;let n=window.bangonit;try{t=await n.capturePage(e)}catch(e){throw Error("could not capture page (page may be navigating)")}let{activeTabId:a}=await n.getTabInfo(e),r="".concat(e,":").concat(null!=a?a:0),i=await f(t);return w.get(r)===i?{type:"not_changed"}:(w.set(r,i),{type:"changed",base64:t})}async function v(e,t){let n=window.bangonit;t.startsWith("http://")||t.startsWith("https://")||(t="https://"+t);let{url:a}=await n.loadURL(e,t);return"Navigated to ".concat(a)}async function x(e){let{ok:t,url:n,reason:a}=await window.bangonit.goBack(e);return t?"Navigated back to ".concat(n):"Cannot go back — ".concat(a)}async function y(e){let{ok:t,url:n,reason:a}=await window.bangonit.goForward(e);return t?"Navigated forward to ".concat(n):"Cannot go forward — ".concat(a)}async function k(e,t){let n=window.bangonit,a=t.action;switch(a){case"list":{let{tabs:t,activeTabId:a}=await n.getTabInfo(e);if(!t.length)return"No tabs open";return t.map(e=>{let t=e.tabId===a?" (active)":"",n=e.isPopup?" (popup)":"";return"Tab ".concat(e.tabId,": ").concat(e.title||"(untitled)"," — ").concat(e.url).concat(t).concat(n)}).join("\n")}case"new":{await n.requestNewTab(e,t.url||"about:blank"),await new Promise(e=>setTimeout(e,3e3));let{activeTabId:a}=await n.getTabInfo(e);return"Opened new tab".concat(t.url?": "+t.url:"",". Active tab is now ").concat(a,".")}case"select":{let a=t.tabId;if(void 0===a)return"Error: tabId required for select";let{tabs:r}=await n.getTabInfo(e);if(!r.find(e=>e.tabId===a))return"Error: tab ".concat(a,' not found. Use browser_tabs with action "list" to see available tabs.');await n.setActiveTab(e,a),await n.requestSelectTab(e,a);let i=r.find(e=>e.tabId===a);return"Switched to tab ".concat(a,": ").concat(null==i?void 0:i.url)}case"close":{var r;let{tabs:a,activeTabId:i}=await n.getTabInfo(e),o=null!==(r=t.tabId)&&void 0!==r?r:i;if(null===o)return"Error: no tab to close";if(!a.find(e=>e.tabId===o))return"Error: tab ".concat(o," not found.");if(a.length<=1)return"Cannot close the last tab.";return await n.requestCloseTab(e,o),"Closed tab ".concat(o)}default:return'Error: unknown tab action "'.concat(a,'". Use list, new, select, or close.')}}async function I(e){let{tabs:t,activeTabId:n}=await window.bangonit.getTabInfo(e);return t.length<=1?"":"\n\nOpen tabs:\n"+t.map(e=>{let t=e.tabId===n?" (active)":"",a=e.isPopup?" (popup)":"";return" Tab ".concat(e.tabId,": ").concat(e.title||"(untitled)"," — ").concat(e.url).concat(t).concat(a)}).join("\n")}async function T(e,t){let n=window.bangonit,a=Math.min(Math.max((null==t?void 0:t.timeout)||10,.1),30),r=null==t?void 0:t.text,i="visible"===((null==t?void 0:t.state)||"visible");if(!r)return await new Promise(e=>setTimeout(e,1e3*a)),"Waited ".concat(a," seconds");let o=Date.now()+1e3*a;for(;Date.now()<o;){let{result:t}=await n.cdpSend(e,"Runtime.evaluate",{expression:"document.body.innerText.includes(".concat(JSON.stringify(r),")"),returnByValue:!0}),a=t.value;if(i&&a)return'Text "'.concat(r,'" is now visible on the page.');if(!i&&!a)return'Text "'.concat(r,'" is no longer visible on the page.');await new Promise(e=>setTimeout(e,500))}return'Timeout: text "'.concat(r,'" ').concat(i?"did not appear":"did not disappear"," within ").concat(a,"s.")}class N{start(){!this.cleanup&&window.bangonit&&(this.cleanup=window.bangonit.onCdpEvent(e=>{"Network.requestWillBeSent"===e.method?this.inflightRequests++:("Network.loadingFinished"===e.method||"Network.loadingFailed"===e.method)&&(this.inflightRequests=Math.max(0,this.inflightRequests-1))}))}stop(){var e;null===(e=this.cleanup)||void 0===e||e.call(this),this.cleanup=null,this.inflightRequests=0}async waitForIdle(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:500,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:2e3,n=Date.now()+t,a=0===this.inflightRequests?Date.now():null;for(;Date.now()<n;){if(0===this.inflightRequests){if(a||(a=Date.now()),Date.now()-a>=e)return}else a=null;await new Promise(e=>setTimeout(e,50))}}constructor(){this.inflightRequests=0,this.cleanup=null}}let C={navigate:"browser_navigate",back:"browser_navigate_back",forward:"browser_go_forward",mouse:"browser_mouse",type:"browser_type",press:"browser_press_key",tabs:"browser_tabs",upload:"browser_upload",wait:"browser_wait_for",close:"browser_close"};var j=n(8204);let E=j.VK("type",[j.Ry({type:j.i0("not_changed")}),j.Ry({type:j.i0("changed"),base64:j.Z_()})]);j.Ry({textOutput:j.Z_(),imageOutput:E.nullable()});let S=Promise.resolve();class R{destroy(){this.networkTracker.stop()}enableRecording(e){this.recorder=e}cursorCallbacks(){let e=this.agentId,t=window.bangonit,n=this.recorder;return{onCursorMove:(a,r)=>{t.emitCursorMove(e,a,r),null==n||n.updateCursor(a,r)},onCursorDown:(a,r)=>{t.emitCursorDown(e,a,r),null==n||n.setCursorDown()},onCursorUp:(a,r)=>{t.emitCursorUp(e,a,r),null==n||n.setCursorUp()},onMouseLock:()=>t.emitMouseLock(e),onMouseUnlock:()=>t.emitMouseUnlock(e)}}async callTool(e,t){switch(e){case"browser_navigate":return v(this.agentId,t.url);case"browser_navigate_back":return x(this.agentId);case"browser_go_forward":return y(this.agentId);case"browser_mouse":{let{result:e,mouseX:n,mouseY:a}=await h(this.agentId,t.steps,this.mouseX,this.mouseY,this.cursorCallbacks());return this.mouseX=n,this.mouseY=a,e}case"browser_type":return m(this.agentId,t.text);case"browser_press_key":return b(this.agentId,t.key);case"browser_close":return k(this.agentId,{action:"close"});case"browser_upload":{var n;if(t.cancel){let e=await window.bangonit.handleFileChooser(this.agentId,"cancel");if(!e.ok)return"Error: ".concat(e.error);return"File picker cancelled."}if(!(null===(n=t.paths)||void 0===n?void 0:n.length))return"Error: provide paths to upload, or cancel: true";let e=await window.bangonit.handleFileChooser(this.agentId,"accept",t.paths);if(!e.ok)return"Error: ".concat(e.error);return"Uploaded ".concat(t.paths.length," file(s).")}case"browser_wait_for":return T(this.agentId,t);case"browser_tabs":return k(this.agentId,t);default:throw Error("Unknown tool: ".concat(e))}}async exec(e){let t=function(){let e;let t=new Promise(t=>{e=t}),n=S;return S=S.then(()=>t),{promise:n,release:e}}();await t.promise;try{return await this._exec(e)}finally{t.release()}}async _exec(e){let{actions:t,observe:n}=e,a=[],r=null;if(this.recorder)try{var i,o,l;let e=await (null===(i=window.bangonit)||void 0===i?void 0:i.getTabInfo(this.agentId)),t=null!==(l=null==e?void 0:e.activeTabId)&&void 0!==l?l:0,n=null==e?void 0:null===(o=e.tabs)||void 0===o?void 0:o.find(e=>e.tabId===t);await this.recorder.startClip(t,null==n?void 0:n.url)}catch(e){console.warn("Failed to start recording clip:",e)}for(let e=0;e<t.length;e++){let n=t[e];if(!n||!n.action)continue;let r=C[n.action];if(!r){a.push("".concat(n.action,": Error — unknown action"));continue}try{let e=this.actionToToolArgs(n),t=await this.callTool(r,e);a.push(t||"OK")}catch(e){a.push("".concat(this.actionLabel(n),": Error — ").concat(e.message))}}if(n){t.length>0&&await this.networkTracker.waitForIdle(500,2e3);try{let e=await I(this.agentId),t=await u(this.agentId,this.mouseX,this.mouseY,e);a.push(t),"snapshot_and_screenshot"===n&&(r=await g(this.agentId))}catch(e){a.push("observe: Error — ".concat(e.message))}}if(this.recorder)try{await this.recorder.stopClip()}catch(e){console.warn("Failed to stop recording clip:",e)}return{textOutput:a.join("\n\n"),imageOutput:r}}actionToToolArgs(e){switch(e.action){case"navigate":return{url:e.url};case"back":case"forward":case"close":default:return{};case"mouse":return{steps:(e.mouseActions||[]).map(e=>{if("wait"===e.action)return{action:"wait",ms:e.ms||100};let t=e.ref?{ref:e.ref}:{x:e.x,y:e.y};return"wheel"===e.action?{action:"wheel",...t,dx:e.dx||0,dy:e.dy||0}:{action:e.action,...t}})};case"type":return{text:e.text};case"press":return{key:e.key};case"upload":return{paths:e.paths,cancel:e.cancel};case"tabs":return{action:e.tabAction,tabId:e.tabId,url:e.url};case"wait":return{timeout:e.timeout}}}actionLabel(e){switch(e.action){case"navigate":return"navigate ".concat(e.url);case"mouse":{let t=(e.mouseActions||[]).map(e=>"wait"===e.action?"wait ".concat(e.ms,"ms"):"wheel"===e.action?"wheel ".concat(e.x,",").concat(e.y," ").concat(e.dx,",").concat(e.dy):"".concat(e.action," ").concat(e.x,",").concat(e.y)).join(" → ");return"mouse ".concat(t)}case"type":return'type "'.concat((e.text||"").slice(0,30),'"');case"press":return"press ".concat(e.key);case"upload":return e.cancel?"upload cancel":"upload ".concat((e.paths||[]).join(", "));case"tabs":return"tabs ".concat(e.tabAction).concat(e.tabId?" "+e.tabId:"");case"wait":return"wait ".concat(e.timeout||10,"s");default:return e.action}}constructor(e){this.mouseX=0,this.mouseY=0,this.networkTracker=new N,this.recorder=null,this.agentId=e,this.networkTracker.start()}}class M{async startClip(e,t){this.currentUrl=t||"",this.recording&&await this.cancelClip(),this.recording=!0,this.currentTabId=e,this.currentFrames=[],this.clipStartTime=Date.now();let n=window.bangonit;this.cdpCleanup=n.onCdpEvent(e=>{if(e.agentId!==this.agentId||"Page.screencastFrame"!==e.method||!this.recording)return;let{data:t,metadata:a,sessionId:r}=e.params;this.currentFrames.push({imageData:t,cursor:{...this.cursorPos},clicking:this.clicking,ts:Date.now(),sessionId:r,deviceWidth:(null==a?void 0:a.deviceWidth)||0,deviceHeight:(null==a?void 0:a.deviceHeight)||0,scrollOffsetX:(null==a?void 0:a.scrollOffsetX)||0,scrollOffsetY:(null==a?void 0:a.scrollOffsetY)||0}),n.cdpSend(this.agentId,"Page.screencastFrameAck",{sessionId:r}).catch(e=>console.error(e))}),await n.cdpSend(this.agentId,"Page.startScreencast",{format:"png",quality:100,maxWidth:1920,maxHeight:1080})}async stopClip(){if(!this.recording)return null;this.recording=!1;let e=Date.now();await window.bangonit.cdpSend(this.agentId,"Page.stopScreencast").catch(e=>console.error(e)),this.cdpCleanup&&(this.cdpCleanup(),this.cdpCleanup=null);let t=this.currentFrames;if(this.currentFrames=[],0===t.length)return null;let n=await this.compositeAndEncode(t);if(!n||0===n.size)return null;let a=new Uint8Array(await n.arrayBuffer()),r="";for(let e=0;e<a.length;e++)r+=String.fromCharCode(a[e]);let i=btoa(r),o={agentId:this.agentId,tabId:this.currentTabId,index:this.clips.length,startTime:this.clipStartTime,endTime:e,url:this.currentUrl||void 0,data:i};return this.clips.push(o),{meta:o}}async cancelClip(){var e;this.recording=!1,this.currentFrames=[],this.cdpCleanup&&(this.cdpCleanup(),this.cdpCleanup=null),await (null===(e=window.bangonit)||void 0===e?void 0:e.cdpSend(this.agentId,"Page.stopScreencast").catch(e=>console.error(e)))}async compositeAndEncode(e){if(0===e.length)return null;let t=await this.decodeFrame(e[0].imageData);if(!t)return null;let n=t.width,a=t.height,r=document.createElement("canvas");r.width=n,r.height=a;let i=r.getContext("2d"),o=r.captureStream(0),l=o.getVideoTracks()[0],s=new MediaRecorder(o,{mimeType:"video/webm;codecs=vp8",videoBitsPerSecond:8e6}),c=[];s.ondataavailable=e=>{e.data.size>0&&c.push(e.data)};let u=new Promise(e=>{s.onstop=()=>{e(new Blob(c,{type:"video/webm"}))}});s.start();let d=[];for(let r=0;r<e.length;r++){let o=e[r],s=0===r?t:await this.decodeFrame(o.imageData);if(!s)continue;let c=o.deviceWidth>0?n/o.deviceWidth:1,u=o.deviceHeight>0?a/o.deviceHeight:1,b=o.cursor.x*c,w=o.cursor.y*u;o.clicking&&(0===r||!e[r-1].clicking)&&d.push({x:b,y:w,startTs:o.ts}),i.clearRect(0,0,n,a),i.drawImage(s,0,0,n,a);for(let e=d.length-1;e>=0;e--){var p,h,m;let t=d[e],n=o.ts-t.startTs;if(n>=400){d.splice(e,1);continue}p=t.x,h=t.y,m=n/400,i.save(),i.beginPath(),i.arc(p,h,24*m,0,2*Math.PI),i.fillStyle="rgba(96, 165, 250, ".concat(.8*(1-m),")"),i.fill(),i.restore(),i.save(),i.beginPath(),i.arc(p,h,32*m,0,2*Math.PI),i.strokeStyle="rgba(96, 165, 250, ".concat(.9*(1-m),")"),i.lineWidth=2,i.stroke(),i.restore()}if(!function(e,t,n,a){e.save(),e.translate(t-2,n-1),e.scale(28/24,28/24);let r=new Path2D("M5 3l14 8.5-6.5 1.5-3.5 6z");e.fillStyle="white",e.strokeStyle="black",e.lineWidth=1.5,e.lineJoin="round",e.fill(r),e.stroke(r),e.restore(),a&&(e.save(),e.beginPath(),e.arc(t,n,4,0,2*Math.PI),e.fillStyle="rgba(59, 130, 246, 0.5)",e.fill(),e.restore())}(i,b,w,o.clicking),l&&"function"==typeof l.requestFrame&&l.requestFrame(),r<e.length-1){let t=Math.max(16,Math.min(e[r+1].ts-o.ts,100));await new Promise(e=>setTimeout(e,t))}}return await new Promise(e=>setTimeout(e,100)),s.stop(),u}async decodeFrame(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);let a=new Blob([n],{type:"image/png"});return createImageBitmap(a)}catch(e){return console.warn("Failed to decode frame:",e),null}}updateCursor(e,t){this.cursorPos={x:e,y:t}}setCursorDown(){this.clicking=!0}setCursorUp(){this.clicking=!1}getClipsMeta(){return[...this.clips]}constructor(e){this.clips=[],this.currentFrames=[],this.cursorPos={x:0,y:0},this.clicking=!1,this.recording=!1,this.currentTabId=0,this.clipStartTime=0,this.cdpCleanup=null,this.ripples=[],this.currentUrl="",this.agentId=e}}function z(e){var t;let{agentId:n,agentName:l,initialPrompt:s,onStatusChange:u,onRerun:d,initialMessages:p,initialTabs:h,initialActiveTabId:m,initialTodos:b,record:w,sessionRecorder:f,onRegisterRecorder:g,planDir:v}=e,[x,y]=(0,r.useState)((null==h?void 0:h.map(e=>({...e,initialUrl:e.url})))||[{id:0,url:"about:blank",title:"",initialUrl:"about:blank"}]),[k,I]=(0,r.useState)(null!=m?m:0),[T,N]=(0,r.useState)(()=>{let e=null==h?void 0:h.find(e=>e.id===(null!=m?m:0));return(null==e?void 0:e.url)||""}),[C,j]=(0,r.useState)(null),[E,S]=(0,r.useState)(!1),[z,A]=(0,r.useState)(!1),_=(0,r.useRef)(new Map),[D,O]=(0,r.useState)(b||[]),U=(0,r.useRef)(null),L=(0,r.useRef)(!1),F=(0,r.useRef)(h?Math.max(...h.map(e=>e.id))+1:1),B=(0,r.useRef)(new Set),[H,W]=(0,r.useState)(0),V=(0,r.useRef)(null),J=(0,r.useRef)(null);!J.current&&window.bangonit&&(J.current=new R(n));let X=(0,r.useRef)(null);w&&!X.current&&J.current&&(X.current=new M(n),J.current.enableRecording(X.current),null==g||g(n,X.current));let q=(0,r.useRef)(f);q.current=f;let Y=(0,r.useMemo)(()=>new o.PD({api:"/api/chat",headers:()=>({"X-Client-Platform":navigator.platform})}),[]),G=(0,r.useRef)(!1),K=(0,r.useCallback)((e,t)=>{var a,r;null===(r=window.bangonit)||void 0===r||null===(a=r.emitAgentOutput)||void 0===a||a.call(r,{agentId:n,type:e,text:t,name:l})},[n,l]),{messages:Z,setMessages:Q,sendMessage:$,addToolOutput:ee,stop:et,status:en,error:ea}=(0,i.RJ)({transport:Y,messages:p,sendAutomaticallyWhen:e=>{let{messages:t}=e;return!G.current&&!E&&(0,o.Qk)({messages:t})},async onToolCall(e){var t,a,r,i,o,s,c,u,d;let{toolCall:p}=e;if("report_result"===p.toolName){let e=p.input,u=(null==e?void 0:e.result)==="pass"?"pass":"fail",d=(null==e?void 0:e.summary)||"";if(K("status","".concat(u.toUpperCase(),": ").concat(d)),j({result:u,summary:d}),q.current){q.current.addEvent({ts:Date.now(),agentId:n,type:"result",data:{result:u,summary:d}});try{let e=await (null===(i=window.bangonit)||void 0===i?void 0:null===(r=i.getRunDir)||void 0===r?void 0:r.call(i));if(e){let t=(null===(o=X.current)||void 0===o?void 0:o.getClipsMeta())||[],a=[{id:n,name:l,result:u,summary:d}],r=q.current.toJSON(a,t);await (null===(c=window.bangonit)||void 0===c?void 0:null===(s=c.generateReplayHtml)||void 0===s?void 0:s.call(c,{runDir:e,data:JSON.stringify(r)}))}}catch(e){console.error(e)}}null===(a=window.bangonit)||void 0===a||null===(t=a.reportTestResult)||void 0===t||t.call(a,{agentId:n,status:u,summary:d}),ee({tool:p.toolName,toolCallId:p.toolCallId,output:"Test result recorded: ".concat(u)});return}if("todos"===p.toolName){let e=p.input,t=(null==e?void 0:e.todos)||D;(null==e?void 0:e.todos)&&O(e.todos),ee({tool:p.toolName,toolCallId:p.toolCallId,output:JSON.stringify(t)});return}if("browser"===p.toolName){try{let e=p.input,t=((null==e?void 0:e.actions)||[]).map(e=>"navigate"===e.action?"navigate ".concat(e.url):"type"===e.action?'type "'.concat((e.text||"").slice(0,30),'"'):"press"===e.action?"press ".concat(e.key):"mouse"===e.action?"mouse ".concat((e.mouseActions||[]).map(e=>"".concat(e.action," ").concat(e.ref||"".concat(e.x,",").concat(e.y))).join(" > ")):e.action).join(", ");K("tool","browser: ".concat(t).concat((null==e?void 0:e.observe)?" [".concat(e.observe,"]"):"")),null===(u=q.current)||void 0===u||u.addEvent({ts:Date.now(),agentId:n,type:"tool-start",data:{tool:"browser",label:t}});let a=J.current,r=a?await a.exec({actions:(null==e?void 0:e.actions)||[],observe:null==e?void 0:e.observe,prompts:null==e?void 0:e.prompts}):{error:"Error: browser tools not available"};null===(d=q.current)||void 0===d||d.addEvent({ts:Date.now(),agentId:n,type:"tool-end",data:{tool:"browser"}}),ee({tool:p.toolName,toolCallId:p.toolCallId,output:G.current?{error:"[Stopped by user]"}:JSON.stringify(r)})}catch(e){ee({tool:p.toolName,toolCallId:p.toolCallId,...G.current?{output:"[Stopped by user]"}:{state:"output-error",errorText:e.message}})}return}}});(0,r.useCallback)(()=>{G.current=!0,et()},[et]);let er="submitted"===en||"streaming"===en;(0,r.useEffect)(()=>{er&&(G.current=!1)},[er]);let ei=Z.length>0,eo=null!==C;(0,r.useEffect)(()=>{if(ei&&!V.current&&(V.current=Date.now()),!ei||eo)return;let e=setInterval(()=>{V.current&&W(Math.floor((Date.now()-V.current)/1e3))},1e3);return()=>clearInterval(e)},[ei,eo]);let el=(0,r.useRef)(null),es=(0,r.useRef)(0);(0,r.useEffect)(()=>{var e;if(0===Z.length)return;let t=Z[Z.length-1];if("assistant"!==t.role)return;let n=(null===(e=t.parts)||void 0===e?void 0:e.filter(e=>"text"===e.type).map(e=>e.text).join(""))||"";t.id!==el.current&&(el.current=t.id,es.current=0);let a=n.slice(es.current);a&&(K("text",a),es.current=n.length)},[Z,K]);let ec=(0,r.useRef)(er),eu=(0,r.useRef)(!1);(0,r.useEffect)(()=>{!eu.current&&ec.current!==er&&(ec.current=er,er?null==u||u(n,"running"):(null==u||u(n,"idle",null==C?void 0:C.result),(null==C?void 0:C.result)&&(eu.current=!0)))},[er,n,u,C]);let ed=(0,r.useRef)(!1),ep=(0,r.useRef)(null);(0,r.useEffect)(()=>{if(ep.current&&(clearTimeout(ep.current),ep.current=null),!er&&!eo&&!E&&!ed.current&&!(Z.length<2))return ep.current=setTimeout(()=>{ep.current=null,ed.current||eo||(ed.current=!0,$({text:"You must call the report_result tool to finalize this test run. Call it now with the result (pass or fail) and a summary."}))},5e3),()=>{ep.current&&clearTimeout(ep.current)}},[er,eo,E,Z.length,$]),(0,r.useEffect)(()=>{var e,t;null===(t=window.bangonit)||void 0===t||null===(e=t.clearPartition)||void 0===e||e.call(t,n)},[n]),(0,r.useEffect)(()=>{q.current&&Z.length>0&&q.current.setMessages(n,Z)},[Z,n]),(0,r.useEffect)(()=>{if(Z.length>0){var e,t,a,r;null===(a=window.bangonit)||void 0===a||a.setAgentSession(n,{messages:Z,initialPrompt:s,tabs:x.filter(e=>!e.isPopup).map(e=>{let{id:t,url:n,title:a}=e;return{id:t,url:n,title:a}}),activeTabId:(null===(e=x.find(e=>e.id===k))||void 0===e?void 0:e.isPopup)?null!==(r=null===(t=x.find(e=>!e.isPopup))||void 0===t?void 0:t.id)&&void 0!==r?r:0:k,todos:D})}},[Z,x,k,n,s,D]);let eh=(0,r.useCallback)(e=>{var t;let a=F.current++;y(t=>[...t,{id:a,url:"about:blank",title:"",initialUrl:e}]),I(a),N("about:blank"===e?"":e),null===(t=window.bangonit)||void 0===t||t.setActiveTab(n,a)},[n]),em=(0,r.useCallback)(e=>{y(t=>{let a=t.findIndex(t=>t.id===e);if(-1===a)return t;let r=t.filter(t=>t.id!==e);return 0===r.length?t:(I(t=>{if(t===e){var i;let e=r[Math.max(0,a-1)].id,t=r.find(t=>t.id===e);return t&&N("about:blank"===t.url?"":t.url),null===(i=window.bangonit)||void 0===i||i.setActiveTab(n,e),e}return t}),r)})},[n]),eb=(0,r.useCallback)(e=>{var t;I(e),null===(t=window.bangonit)||void 0===t||t.setActiveTab(n,e),y(t=>{let n=t.find(t=>t.id===e);return n&&N("about:blank"===n.url?"":n.url),t})},[n]),ew=(0,r.useRef)(eh),ef=(0,r.useRef)(em),eg=(0,r.useRef)(eb);ew.current=eh,ef.current=em,eg.current=eb,(0,r.useEffect)(()=>{var e,t,a,r,i;let o=[],l=e=>{e&&o.push(e)};return l(null===(e=window.bangonit)||void 0===e?void 0:e.onTabUpdated(e=>{if(e.agentId!==n)return;let t="about:blank"===e.url,a="about:blank"===e.title;y(n=>n.map(n=>n.id===e.tabId?{...n,...!t&&void 0!==e.url&&{url:e.url},...!a&&void 0!==e.title&&{title:e.title}}:n)),void 0===e.url||t||I(t=>(t===e.tabId&&N(e.url),t))})),l(null===(t=window.bangonit)||void 0===t?void 0:t.onOpenNewTab(e=>{e.agentId===n&&ew.current(e.url)})),l(null===(a=window.bangonit)||void 0===a?void 0:a.onPopupOpened(e=>{e.agentId===n&&y(t=>[...t,{id:e.tabId,url:e.url||"about:blank",title:"",initialUrl:e.url||"about:blank",isPopup:!0}])})),l(null===(r=window.bangonit)||void 0===r?void 0:r.onCloseTab(e=>{e.agentId===n&&ef.current(e.tabId)})),l(null===(i=window.bangonit)||void 0===i?void 0:i.onSelectTab(e=>{e.agentId===n&&eg.current(e.tabId)})),()=>o.forEach(e=>null==e?void 0:e())},[n]),(0,r.useEffect)(()=>{L.current||(null==p?void 0:p.length)||(L.current=!0,$({text:s}))},[s,$,p]),(0,r.useEffect)(()=>{var e;null===(e=U.current)||void 0===e||e.scrollIntoView({behavior:"smooth"})},[Z]);let ev=(0,r.useCallback)((e,t,a)=>{if(!e)return;_.current.set(t,e);let r=()=>{if(!B.current.has(t))try{var r,i,o;let l=null===(r=e.getWebContentsId)||void 0===r?void 0:r.call(e);l&&(B.current.add(t),null===(i=window.bangonit)||void 0===i||i.registerTab(n,t,l,a,v),t===k&&(null===(o=window.bangonit)||void 0===o||o.setActiveTab(n,t)))}catch(e){console.error(e)}};r(),e.addEventListener("did-attach",r),e.addEventListener("close",()=>ef.current(t)),e._consoleListenerAttached||(e._consoleListenerAttached=!0,e.addEventListener("console-message",e=>{var t,a,r;null===(a=window.bangonit)||void 0===a||null===(t=a.emitConsoleMessage)||void 0===t||t.call(a,{agentId:n,level:e.level,message:e.message,url:e.sourceId||"",line:e.lineNumber||0}),null===(r=q.current)||void 0===r||r.addConsoleLog(n,e.level,e.message,e.sourceId||"",e.lineNumber||0)}))},[n,k]),ex=e=>"".concat(Math.floor(e/60),":").concat((e%60).toString().padStart(2,"0"));return(0,a.jsxs)("div",{className:"flex h-full w-full bg-zinc-950 overflow-hidden",children:[(0,a.jsxs)("div",{className:"flex-1 flex flex-col border-r border-zinc-800 min-w-0",children:[(0,a.jsx)("div",{className:"flex items-center bg-zinc-900 border-b border-zinc-800 overflow-x-auto",children:x.map(e=>(0,a.jsx)("button",{onClick:()=>eb(e.id),className:"flex items-center gap-1.5 px-3 py-2 text-xs border-r border-zinc-800 min-w-0 max-w-[200px] shrink-0\n ".concat(e.id===k?"bg-zinc-800 text-zinc-200":"text-zinc-500 hover:text-zinc-300 hover:bg-zinc-850"),children:(0,a.jsxs)("span",{className:"truncate",children:[e.isPopup?"↗ ":"",e.title||(e.url&&"about:blank"!==e.url?e.url:"New Tab")]})},e.id))}),(0,a.jsx)("div",{className:"flex items-center gap-2 px-3 py-2 bg-zinc-900 border-b border-zinc-800",children:(0,a.jsx)("div",{className:"flex-1 px-3 py-1.5 bg-zinc-800 border border-zinc-700 rounded-lg text-xs text-zinc-400 truncate",children:T||"about:blank"})}),(0,a.jsxs)("div",{className:"flex-1 relative bg-white overflow-hidden",onWheel:e=>e.stopPropagation(),children:[x.map(e=>e.isPopup?e.id===k&&(0,a.jsxs)("div",{className:"absolute inset-0 flex items-center justify-center bg-zinc-900 text-zinc-400 text-sm z-[1]",children:["Popup window open — ",e.title||e.url]},e.id):(0,a.jsx)("webview",{ref:t=>ev(t,e.id,e.initialUrl),src:"about:blank",partition:"persist:agent-".concat(n),allowpopups:"",style:{width:"100%",height:"100%",position:"absolute",backgroundColor:"white",top:0,left:0,pointerEvents:e.id===k?"auto":"none",zIndex:e.id===k?1:0}},e.id)),!(null===(t=x.find(e=>e.id===k))||void 0===t?void 0:t.isPopup)&&(0,a.jsx)(c,{agentId:n}),!eo&&(0,a.jsx)("div",{className:"absolute inset-0 z-10 cursor-not-allowed"})]})]}),(0,a.jsxs)("div",{className:"w-[420px] flex flex-col h-full shrink-0",children:[(0,a.jsxs)("div",{className:"flex items-center px-4 py-3 border-b border-zinc-800",children:[(0,a.jsx)("h2",{className:"text-sm font-medium text-zinc-300",children:l}),(0,a.jsx)("div",{className:"flex-1"})]}),C&&(0,a.jsxs)("div",{className:"px-4 py-2 text-sm border-b flex items-center gap-3 ".concat("pass"===C.result?"bg-green-950/30 border-green-900/50":"bg-red-950/30 border-red-900/50"),children:[(0,a.jsx)("span",{className:"font-medium ".concat("pass"===C.result?"text-green-400":"text-red-400"),children:"pass"===C.result?"PASSED":"FAILED"}),(0,a.jsx)("span",{className:"text-zinc-500 text-xs",children:ex(H)}),C.summary&&(0,a.jsx)("span",{className:"text-zinc-400 text-xs truncate flex-1",children:C.summary})]}),D.length>0&&(0,a.jsx)("div",{className:"text-xs space-y-1 px-4 py-2 border-b border-zinc-800 bg-zinc-900/80 shrink-0 max-h-48 overflow-y-auto",children:D.map((e,t)=>(0,a.jsxs)("div",{className:"flex items-center gap-2 ".concat("completed"===e.status?"text-zinc-500":"text-zinc-300"),children:[(0,a.jsx)("span",{className:"shrink-0",children:"completed"===e.status?"✓":"in_progress"===e.status?(0,a.jsx)("span",{className:"inline-block w-2 h-2 bg-blue-500 rounded-full animate-pulse"}):"○"}),(0,a.jsx)("span",{className:"completed"===e.status?"line-through":"",children:e.content})]},t))}),(0,a.jsxs)("div",{className:"flex-1 overflow-y-auto px-4 py-4 space-y-3",children:[Z.map(e=>(0,a.jsx)(P,{message:e,agentName:l},e.id)),ea&&(0,a.jsx)("div",{className:"text-sm px-3 py-2 bg-red-950/30 border border-red-900/50 rounded-lg text-red-400",children:ea.message}),(0,a.jsx)("div",{ref:U})]}),(0,a.jsx)("div",{className:"px-4 py-2 border-t border-zinc-800 flex items-center gap-3 shrink-0",children:eo?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full shrink-0 ".concat("pass"===C.result?"bg-green-500":"bg-red-500")}),(0,a.jsxs)("span",{className:"text-xs font-medium ".concat("pass"===C.result?"text-green-400":"text-red-400"),children:["pass"===C.result?"Passed":"Failed"," in ",ex(H)]}),(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("button",{onClick:()=>{let e=_.current.get(k);e&&(z?e.closeDevTools():e.openDevTools(),A(!z))},className:"text-xs px-2 py-1 rounded border transition-colors ".concat(z?"border-blue-600 text-blue-400 bg-blue-950/30":"border-zinc-700 hover:border-zinc-500 text-zinc-500 hover:text-zinc-300"),title:"Toggle DevTools",children:"DevTools"}),(0,a.jsx)("button",{onClick:()=>{var e,t;null===(t=window.bangonit)||void 0===t||null===(e=t.emitTestRerun)||void 0===e||e.call(t),null==d||d()},className:"text-xs px-3 py-1 rounded border border-zinc-700 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 transition-colors",children:"Rerun"})]}):ei?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full shrink-0 ".concat(E?"bg-amber-500":"bg-blue-500 animate-pulse")}),(0,a.jsxs)("span",{className:"text-xs text-zinc-400",children:[E?"Paused":"Working"," ",ex(H)]}),(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("button",{onClick:()=>{let e=_.current.get(k);e&&(z?e.closeDevTools():e.openDevTools(),A(!z))},className:"text-xs px-2 py-1 rounded border transition-colors ".concat(z?"border-blue-600 text-blue-400 bg-blue-950/30":"border-zinc-700 hover:border-zinc-500 text-zinc-500 hover:text-zinc-300"),title:"Toggle DevTools",children:"DevTools"}),(0,a.jsx)("button",{onClick:()=>S(!E),className:"text-xs px-2 py-1 rounded border border-zinc-700 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 transition-colors",children:E?"Continue":"Pause"})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 bg-zinc-600 rounded-full shrink-0"}),(0,a.jsx)("span",{className:"text-xs text-zinc-500",children:"Queued"})]})})]})]})}function P(e){var t,n;let{message:r,agentName:i}=e;if("user"===r.role){let e=null===(n=r.parts)||void 0===n?void 0:n.find(e=>"text"===e.type);return(0,a.jsxs)("div",{className:"text-sm",children:[(0,a.jsx)("span",{className:"text-xs text-zinc-500 block mb-1",children:"Test Plan"}),(0,a.jsx)("div",{className:"text-zinc-200 prose prose-invert prose-sm max-w-none",children:(0,a.jsx)(l.UG,{remarkPlugins:[s.Z],children:(null==e?void 0:e.text)||""})})]})}return(0,a.jsx)("div",{className:"text-sm space-y-2",children:null===(t=r.parts)||void 0===t?void 0:t.map((e,t)=>{var n,r;if("text"===e.type&&e.text)return(null===(r=e.providerMetadata)||void 0===r?void 0:null===(n=r.anthropic)||void 0===n?void 0:n.type)==="compaction"?null:(0,a.jsxs)("div",{children:[(0,a.jsx)("span",{className:"text-xs text-zinc-500 block mb-1",children:i}),(0,a.jsx)("div",{className:"text-zinc-300 prose prose-invert prose-sm max-w-none",children:(0,a.jsx)(l.UG,{remarkPlugins:[s.Z],children:e.text})})]},t);if("dynamic-tool"===e.type||"string"==typeof e.type&&e.type.startsWith("tool-")){let n=e.toolName||("string"==typeof e.type?e.type.replace(/^tool-/,""):"");return"todos"===n||"report_result"===n?null:(0,a.jsx)(A,{part:e},t)}return null})})}function A(e){let{part:t}=e,[n,i]=(0,r.useState)(!1),o=t.input||{},l=t.output,s=t.state||"input-available",c=t.toolName||("string"==typeof t.type?t.type.replace(/^tool-/,""):""),u="input-streaming"===s?"":"browser"===c?(()=>{let e=(o.actions||[]).map(e=>{switch(e.action){case"navigate":return"navigate ".concat(e.url||"");case"mouse":{let t=(e.mouseActions||[]).map(e=>"wait"===e.action?"wait ".concat(e.ms,"ms"):"wheel"===e.action?"wheel ".concat(e.ref||"".concat(e.x,",").concat(e.y)):"".concat(e.action," ").concat(e.ref||"".concat(e.x,",").concat(e.y))).join(" → ");return"mouse ".concat(t)}case"type":return'type "'.concat((e.text||"").slice(0,40),'"');case"press":return"press ".concat(e.key||"");case"tabs":return"tabs ".concat(e.tabAction||"").concat(e.tabId?" "+e.tabId:"");default:return e.action||""}});return o.observe&&e.push(o.observe),e.join(", ")})():o.command||(Object.keys(o).length>0?JSON.stringify(o):"");return(0,a.jsxs)("div",{className:"text-sm",children:[(0,a.jsxs)("button",{onClick:()=>i(!n),className:"flex items-center gap-2 text-xs px-2 py-1.5 bg-zinc-900 border border-zinc-800 rounded-lg hover:border-zinc-700 transition-colors w-full text-left min-w-0",children:["input-streaming"===s||"input-available"===s?(0,a.jsx)("span",{className:"inline-block w-2 h-2 bg-amber-500 rounded-full animate-pulse shrink-0"}):(0,a.jsx)("span",{className:"text-green-500 shrink-0",children:"✓"}),(0,a.jsx)("span",{className:"text-zinc-400 font-mono truncate",children:u}),(0,a.jsx)("span",{className:"ml-auto transition-transform text-zinc-600 shrink-0 ".concat(n?"rotate-90":""),children:"▶"})]}),n&&(0,a.jsxs)("pre",{className:"mt-1 px-3 py-2 bg-zinc-900/50 rounded-lg border border-zinc-800 text-xs whitespace-pre-wrap overflow-x-auto max-h-60 overflow-y-auto",children:[u&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("span",{className:"text-zinc-300 select-all",children:["$ ",u]}),"\n"]}),null!=l&&(()=>{if("browser"===c&&"string"==typeof l)try{let e=JSON.parse(l);if(void 0!==e.textOutput)return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("span",{className:"text-zinc-500",children:e.textOutput}),e.imageOutput&&(0,a.jsxs)(a.Fragment,{children:["\n",(0,a.jsx)("span",{className:"changed"===e.imageOutput.type?"text-blue-400":"text-zinc-600",children:"changed"===e.imageOutput.type?"[screenshot: changed]":"[screenshot: unchanged]"})]})]})}catch(e){console.error(e)}return(0,a.jsx)("span",{className:"text-zinc-500",children:"string"==typeof l?l:JSON.stringify(l,null,2)})})()]})]})}let _={0:"debug",1:"log",2:"warn",3:"error"};class D{addEvent(e){this.events.push(e)}setMessages(e,t){let n=Date.now(),a=JSON.parse(JSON.stringify(t));for(let t=0;t<a.length;t++){let r=a[t],i="".concat(e,":").concat(t);if(this.seenParts.has(i)||this.seenParts.set(i,n),r._ts=this.seenParts.get(i),r.parts)for(let a=0;a<r.parts.length;a++){let i="".concat(e,":").concat(t,":").concat(a);this.seenParts.has(i)||this.seenParts.set(i,n),r.parts[a]._ts=this.seenParts.get(i)}}this.messages.set(e,a)}addConsoleLog(e,t,n,a,r){this.consoleLogs.has(e)||this.consoleLogs.set(e,[]),this.consoleLogs.get(e).push({ts:Date.now(),level:_[t]||"log",message:n,url:a,line:r})}toJSON(e,t){return{runId:this.runId,startTime:this.startTime,endTime:Date.now(),agents:e,timeline:[...this.events].sort((e,t)=>e.ts-t.ts),messages:Object.fromEntries(this.messages),consoleLogs:Object.fromEntries(this.consoleLogs),clips:t}}constructor(e){this.events=[],this.messages=new Map,this.consoleLogs=new Map,this.seenParts=new Map,this.runId=e,this.startTime=Date.now()}}function O(){let[e,t]=(0,r.useState)([]),[n,i]=(0,r.useState)({}),[o,l]=(0,r.useState)({}),[s,c]=(0,r.useState)(!1),[u,d]=(0,r.useState)({}),p=(0,r.useRef)(new Map),[h,m]=(0,r.useState)(null),[b,w]=(0,r.useState)(!1),[f,g]=(0,r.useState)(!1),v=(0,r.useRef)(null),x=(0,r.useRef)(new Map);(0,r.useEffect)(()=>{(async()=>{var e,n,a,r,o;let s=await (null===(e=window.bangonit)||void 0===e?void 0:e.getAgents())||[];if(0===s.length){let e={id:crypto.randomUUID(),name:"Test 1",createdAt:Date.now()};s.push(e),await (null===(a=window.bangonit)||void 0===a?void 0:a.setAgents(s))}t(s);let u={},d={};for(let e of s){let t=await (null===(r=window.bangonit)||void 0===r?void 0:r.getAgentSession(e.id));t&&(null===(o=t.messages)||void 0===o?void 0:o.length)>0&&(u[e.id]={initialPrompt:t.initialPrompt,initialMessages:t.messages.map(e=>{if("assistant"!==e.role||!e.parts)return e;let t=e.parts.map(e=>"tool-invocation"===e.type&&"result"!==e.state?{...e,state:"result",output:"[Interrupted — app was restarted]"}:e);return{...e,parts:t}}),initialTabs:t.tabs,initialActiveTabId:t.activeTabId,initialTodos:t.todos},d[e.id]="idle")}l(u),i(d),m((null===(n=s[0])||void 0===n?void 0:n.id)||null),c(!0)})()},[]);let y=(0,r.useRef)(e);y.current=e,(0,r.useEffect)(()=>{if(s&&e.length>0){var t;null===(t=window.bangonit)||void 0===t||t.setAgents(e)}},[e,s]);let k=(0,r.useCallback)(async e=>{var t,n;await (null===(n=window.bangonit)||void 0===n?void 0:null===(t=n.clearPartition)||void 0===t?void 0:t.call(n,e));let a=o[e];a&&(i(t=>({...t,[e]:"running"})),d(t=>({...t,[e]:(t[e]||0)+1})),l(t=>({...t,[e]:{initialPrompt:a.initialPrompt}})))},[o]),I=(0,r.useCallback)((e,t)=>{x.current.set(e,t)},[]),T=(0,r.useRef)(n);T.current=n;let N=(0,r.useCallback)(async(e,t)=>{var n,a,r,i;let o=v.current;if(!o)return;let l=await (null===(a=window.bangonit)||void 0===a?void 0:null===(n=a.getRunDir)||void 0===n?void 0:n.call(a));if(!l)return;let s=[];for(let e of x.current.values())s.push(...e.getClipsMeta());let c={...T.current,[e]:t},u=y.current.map(e=>{let t=c[e.id];return{id:e.id,name:e.name,result:"completed"===t?"pass":"failed"===t?"fail":void 0}}),d=o.toJSON(u,s);await (null===(i=window.bangonit)||void 0===i?void 0:null===(r=i.generateReplayHtml)||void 0===r?void 0:r.call(i,{runDir:l,data:JSON.stringify(d)}))},[]),C=(0,r.useCallback)((e,t,n)=>{let a;if(a="running"===t?"running":"pass"===n?"completed":"fail"===n?"failed":"idle",i(t=>({...t,[e]:a})),b&&("pass"===n||"fail"===n)&&N(e,a),"fail"===n){let t=p.current.get(e);if(t&&t.attempt<t.maxRetries){var r,o;t.attempt++,null===(o=window.bangonit)||void 0===o||null===(r=o.emitTestRetry)||void 0===r||r.call(o,{agentId:e,attempt:t.attempt,maxRetries:t.maxRetries}),setTimeout(()=>k(e),1e3)}}},[k,b,N]),j=(0,r.useCallback)((e,n,a)=>{a&&t(t=>t.map(t=>t.id===e?{...t,name:a}:t)),l(t=>({...t,[e]:{initialPrompt:n}})),i(t=>({...t,[e]:"running"})),m(e)},[]),E=(0,r.useCallback)(()=>{let n=crypto.randomUUID(),a={id:n,name:"Test ".concat(e.length+1),createdAt:Date.now()};t(e=>[...e,a]),m(n)},[e.length]);if((0,r.useEffect)(()=>{var e,n;let a=null===(n=window.bangonit)||void 0===n?void 0:null===(e=n.onTestPlan)||void 0===e?void 0:e.call(n,e=>{g(!0);let{agentIndex:n,testPlan:a,name:r,retries:o,extraPrompt:s,record:c,planDir:u}=e;if(c&&!v.current){let e=new Date().toISOString().replace(/[:.]/g,"-");v.current=new D(e),w(!0)}t(e=>{let t=n+1,a=[...e];for(;a.length<t;)a.push({id:crypto.randomUUID(),name:r||"Test ".concat(a.length+1),createdAt:Date.now()});return r&&(a=a.map((e,t)=>t===n?{...e,name:r}:e)),a}),setTimeout(()=>{t(e=>{let t=e[n];if(!t)return e;let r=s?"".concat(a,"\n\n## Additional Instructions\n").concat(s):a;return l(e=>({...e,[t.id]:{initialPrompt:r,planDir:u}})),i(e=>({...e,[t.id]:"running"})),o&&o>0&&p.current.set(t.id,{maxRetries:o,attempt:0,testPlan:r}),0===n&&m(t.id),e})},100)});return()=>null==a?void 0:a()},[]),(0,r.useEffect)(()=>{var e,t;let n=null===(t=window.bangonit)||void 0===t?void 0:null===(e=t.onFocusAgent)||void 0===e?void 0:e.call(t,e=>{m(e.agentId)});return()=>null==n?void 0:n()},[]),!s)return(0,a.jsx)("div",{className:"flex h-screen bg-zinc-950"});e.some(e=>o[e.id]);let S=e.find(e=>e.id===h),R=!!h&&!!o[h];return(0,a.jsxs)("div",{className:"flex h-screen bg-zinc-950 overflow-hidden",children:[(0,a.jsxs)("div",{className:"flex flex-col bg-zinc-900 border-r border-zinc-800 shrink-0 w-48 overflow-y-auto",children:[(0,a.jsxs)("div",{className:"flex items-center px-3 py-2 border-b border-zinc-800",children:[(0,a.jsx)("span",{className:"text-xs font-medium text-zinc-500 uppercase tracking-wider",children:"Tests"}),(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("button",{onClick:E,className:"text-zinc-500 hover:text-zinc-300 transition-colors text-lg leading-none",title:"Add test",children:"+"})]}),e.map(e=>{let t=n[e.id];return o[e.id],(0,a.jsx)("button",{onClick:()=>m(e.id),className:"px-3 py-2 text-xs text-left border-b border-zinc-800 transition-colors\n ".concat(e.id===h?"bg-zinc-800 text-zinc-200":"text-zinc-500 hover:text-zinc-300"),children:(0,a.jsxs)("span",{className:"flex items-center gap-2",children:[(0,a.jsx)("span",{className:"inline-block w-2 h-2 rounded-full shrink-0 ".concat("running"===t?"bg-blue-500 animate-pulse":"completed"===t?"bg-green-500":"failed"===t?"bg-red-500":"bg-zinc-600")}),(0,a.jsx)("span",{className:"truncate",children:e.name})]})},e.id)})]}),(0,a.jsxs)("div",{className:"flex-1 min-w-0 h-full relative",children:[e.map(e=>o[e.id]?(0,a.jsx)("div",{className:"absolute inset-0 z-0",style:{display:"flex",zIndex:e.id===h?1:0,pointerEvents:e.id===h?"auto":"none"},children:(0,a.jsx)(z,{agentId:e.id,agentName:e.name,initialPrompt:o[e.id].initialPrompt,initialMessages:o[e.id].initialMessages,initialTabs:o[e.id].initialTabs,initialActiveTabId:o[e.id].initialActiveTabId,initialTodos:o[e.id].initialTodos,onStatusChange:C,onRerun:()=>k(e.id),record:b,sessionRecorder:v.current||void 0,onRegisterRecorder:I,planDir:o[e.id].planDir})},"".concat(e.id,"-").concat(u[e.id]||0)):null),S&&!R&&!f&&(0,a.jsx)(U,{agentId:S.id,agentName:S.name,onSubmit:j})]})]})}function U(e){let{agentId:t,agentName:n,onSubmit:i}=e,[o,l]=(0,r.useState)(""),s=(0,r.useRef)(null);(0,r.useEffect)(()=>{var e;null===(e=s.current)||void 0===e||e.focus()},[t]);let c=()=>{let e=o.trim();e&&i(t,e)};return(0,a.jsx)("div",{className:"absolute inset-0 flex items-center justify-center z-10 bg-zinc-950",children:(0,a.jsxs)("div",{className:"w-full max-w-xl px-6",children:[(0,a.jsx)("h2",{className:"text-lg font-medium text-zinc-200 mb-4",children:"What would you like to test?"}),(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)("textarea",{ref:s,value:o,onChange:e=>l(e.target.value),onKeyDown:e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),c())},placeholder:"Describe what to test in plain English...",className:"w-full px-4 py-3 bg-zinc-800 border border-zinc-700 rounded-lg text-sm text-zinc-200 placeholder-zinc-500 resize-none focus:outline-none focus:border-zinc-500 transition-colors",rows:4}),(0,a.jsx)("button",{onClick:c,disabled:!o.trim(),className:"absolute bottom-3 right-3 px-3 py-1.5 bg-blue-600 hover:bg-blue-500 disabled:bg-zinc-700 disabled:text-zinc-500 text-white text-xs font-medium rounded transition-colors",children:"Run"})]}),(0,a.jsx)("p",{className:"text-xs text-zinc-600 mt-2",children:"Press Enter to run. Shift+Enter for a new line."}),(0,a.jsxs)("div",{className:"mt-4",children:[(0,a.jsx)("p",{className:"text-xs text-zinc-600 mb-2",children:"Examples:"}),(0,a.jsx)("div",{className:"flex flex-col gap-1.5",children:["Go to example.com and verify the homepage loads with a heading","Navigate to my-app.com/login, sign in with test@example.com / password123, and verify the dashboard loads","Go to localhost:3000, add an item to the cart, proceed to checkout, and verify the order summary"].map((e,t)=>(0,a.jsx)("button",{onClick:()=>l(e),className:"text-left text-xs text-zinc-500 hover:text-zinc-300 bg-zinc-900 hover:bg-zinc-800 px-3 py-2 rounded border border-zinc-800 transition-colors",children:e},t))})]})]})})}function L(){return(0,a.jsx)(O,{})}}},function(e){e.O(0,[46,631,293,528,744],function(){return e(e.s=6421)}),_N_E=e.O()}]);
|
|
@@ -55,7 +55,8 @@ Actions:
|
|
|
55
55
|
IMPORTANT: Mouse actions move a real cursor across the screen. The cursor travels from its current position to the target, which may trigger hover effects (tooltips, dropdowns, highlights) on elements along the path. If a hover side-effect disrupts your intended action (e.g. a menu opens over your click target), take a fresh snapshot and retry. You can also use this to your advantage — use "move" to intentionally hover over elements to reveal tooltips or dropdown menus.
|
|
56
56
|
type <text> — type text at cursor (keystrokes)
|
|
57
57
|
press <key> — press a key or combo (Enter, Tab, ${mod}+a, Shift+Enter)
|
|
58
|
-
|
|
58
|
+
upload --paths=["/path/to/file"] — upload files to an open file picker (the snapshot will tell you when a file picker is open)
|
|
59
|
+
upload --cancel=true — cancel/dismiss an open file picker
|
|
59
60
|
tabs --action=list — list open tabs
|
|
60
61
|
tabs --action=new --url=<url> — open new tab
|
|
61
62
|
tabs --action=select --tabId=<id> — switch tab
|
|
@@ -95,7 +96,7 @@ Good — drag from one point to another:
|
|
|
95
96
|
{ actions: [{"action":"mouse","mouseActions":[{"action":"down","x":100,"y":200},{"action":"move","x":300,"y":400},{"action":"up","x":300,"y":400}]}] }
|
|
96
97
|
|
|
97
98
|
## Dialogs and file pickers
|
|
98
|
-
JavaScript dialogs are automatically handled: alert() is suppressed, confirm() returns true, and prompt() returns the default value.
|
|
99
|
+
JavaScript dialogs are automatically handled: alert() is suppressed, confirm() returns true, and prompt() returns the default value. File picker dialogs are intercepted — they will not visually appear, but the snapshot will show "[File picker is open]" when one is triggered. Use the "upload" action to provide file paths or cancel the picker.
|
|
99
100
|
|
|
100
101
|
## Todo tracking
|
|
101
102
|
For tasks with 3+ distinct steps, call the todos tool to show progress. Call it with the FULL list each time:
|
|
@@ -105,7 +106,7 @@ For tasks with 3+ distinct steps, call the todos tool to show progress. Call it
|
|
|
105
106
|
Keep todos short (5-10 words each). The user watches your progress in real time, so update todos promptly after each step finishes.
|
|
106
107
|
To read the current todo list, call todos without the "todos" parameter. Only you can write todos, so you normally don't need to read them — use this only when you've lost track (e.g. after context was compacted).
|
|
107
108
|
|
|
108
|
-
Be concise. The user watches your actions in real time.`;
|
|
109
|
+
Be concise and token-efficient. Don't narrate every step — just act. Summarize successes and failures briefly (e.g. "3 todos added, footer shows correct count" not a blow-by-blow of each click). The user watches your actions in real time.`;
|
|
109
110
|
|
|
110
111
|
// Prepend project-level system prompt
|
|
111
112
|
if (projectPrompt) {
|
|
@@ -163,7 +164,7 @@ export function createChatHandler() {
|
|
|
163
164
|
properties: {
|
|
164
165
|
action: {
|
|
165
166
|
type: "string",
|
|
166
|
-
enum: ["navigate", "back", "forward", "mouse", "type", "press", "
|
|
167
|
+
enum: ["navigate", "back", "forward", "mouse", "type", "press", "upload", "tabs", "wait", "close"],
|
|
167
168
|
description: "The browser action to perform",
|
|
168
169
|
},
|
|
169
170
|
url: { type: "string", description: "URL for navigate or new tab" },
|
|
@@ -185,6 +186,8 @@ export function createChatHandler() {
|
|
|
185
186
|
required: ["action"],
|
|
186
187
|
},
|
|
187
188
|
},
|
|
189
|
+
paths: { type: "array", items: { type: "string" }, description: "File paths for upload" },
|
|
190
|
+
cancel: { type: "boolean", description: "Cancel file picker" },
|
|
188
191
|
tabAction: { type: "string", enum: ["list", "new", "close", "select"] },
|
|
189
192
|
tabId: { type: "number" },
|
|
190
193
|
timeout: { type: "number" },
|
|
@@ -25,12 +25,13 @@ interface TestPlanMessage {
|
|
|
25
25
|
retries?: number;
|
|
26
26
|
extraPrompt?: string;
|
|
27
27
|
record?: boolean;
|
|
28
|
+
planDir?: string;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export default function AppShell() {
|
|
31
32
|
const [agents, setAgents] = useState<AgentConfig[]>([]);
|
|
32
33
|
const [agentStatuses, setAgentStatuses] = useState<Record<string, AgentStatus>>({});
|
|
33
|
-
const [agentSessions, setAgentSessions] = useState<Record<string, { initialPrompt: string; initialMessages?: any[]; initialTabs?: { id: number; url: string; title: string }[]; initialActiveTabId?: number; initialTodos?: { content: string; status: "pending" | "in_progress" | "completed" }[] }>>({});
|
|
34
|
+
const [agentSessions, setAgentSessions] = useState<Record<string, { initialPrompt: string; initialMessages?: any[]; initialTabs?: { id: number; url: string; title: string }[]; initialActiveTabId?: number; initialTodos?: { content: string; status: "pending" | "in_progress" | "completed" }[]; planDir?: string }>>({});
|
|
34
35
|
const [loaded, setLoaded] = useState(false);
|
|
35
36
|
const [retryKeys, setRetryKeys] = useState<Record<string, number>>({});
|
|
36
37
|
const retryConfigRef = useRef<Map<string, { maxRetries: number; attempt: number; testPlan: string }>>(new Map());
|
|
@@ -130,8 +131,7 @@ export default function AppShell() {
|
|
|
130
131
|
});
|
|
131
132
|
|
|
132
133
|
const data = sr.toJSON(agentInfo, allClips);
|
|
133
|
-
await window.bangonit?.
|
|
134
|
-
await window.bangonit?.generateReplayHtml?.({ runDir });
|
|
134
|
+
await window.bangonit?.generateReplayHtml?.({ runDir, data: JSON.stringify(data) });
|
|
135
135
|
}, []);
|
|
136
136
|
|
|
137
137
|
const handleStatusChange = useCallback((agentId: string, status: "running" | "idle", result?: "pass" | "fail") => {
|
|
@@ -182,7 +182,7 @@ export default function AppShell() {
|
|
|
182
182
|
useEffect(() => {
|
|
183
183
|
const cleanup = window.bangonit?.onTestPlan?.((data: TestPlanMessage) => {
|
|
184
184
|
setCliMode(true);
|
|
185
|
-
const { agentIndex, testPlan, name, retries, extraPrompt, record: doRecord } = data;
|
|
185
|
+
const { agentIndex, testPlan, name, retries, extraPrompt, record: doRecord, planDir } = data;
|
|
186
186
|
|
|
187
187
|
if (doRecord && !sessionRecorderRef.current) {
|
|
188
188
|
const runId = new Date().toISOString().replace(/[:.]/g, "-");
|
|
@@ -217,7 +217,7 @@ export default function AppShell() {
|
|
|
217
217
|
|
|
218
218
|
setAgentSessions((prev) => ({
|
|
219
219
|
...prev,
|
|
220
|
-
[agent.id]: { initialPrompt: prompt },
|
|
220
|
+
[agent.id]: { initialPrompt: prompt, planDir },
|
|
221
221
|
}));
|
|
222
222
|
setAgentStatuses((prev) => ({ ...prev, [agent.id]: "running" }));
|
|
223
223
|
if (retries && retries > 0) {
|
|
@@ -313,6 +313,7 @@ export default function AppShell() {
|
|
|
313
313
|
record={recording}
|
|
314
314
|
sessionRecorder={sessionRecorderRef.current || undefined}
|
|
315
315
|
onRegisterRecorder={registerBrowserRecorder}
|
|
316
|
+
planDir={agentSessions[agent.id].planDir}
|
|
316
317
|
/>
|
|
317
318
|
</div>
|
|
318
319
|
) : null
|