@zibby/core 0.1.31 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/agents/base.js +319 -14
  2. package/dist/backend-client.js +1 -1
  3. package/dist/constants/tool-names.js +1 -1
  4. package/dist/constants/zibby-scratch.js +1 -1
  5. package/dist/constants.js +1 -1
  6. package/dist/enrichment/base.js +1 -1
  7. package/dist/enrichment/enrichers/accessibility-enricher.js +1 -1
  8. package/dist/enrichment/enrichers/dom-enricher.js +1 -1
  9. package/dist/enrichment/enrichers/page-state-enricher.js +1 -1
  10. package/dist/enrichment/enrichers/position-enricher.js +1 -1
  11. package/dist/enrichment/index.js +4 -1
  12. package/dist/enrichment/mcp-integration.js +4 -1
  13. package/dist/enrichment/mcp-ref-enricher.js +1 -1
  14. package/dist/enrichment/pipeline.js +2 -2
  15. package/dist/enrichment/trace-text-enricher.js +2 -1
  16. package/dist/framework/agents/assistant-strategy.js +69 -5
  17. package/dist/framework/agents/base.js +1 -1
  18. package/dist/framework/agents/claude-strategy.js +107 -4
  19. package/dist/framework/agents/codex-strategy.js +23 -4
  20. package/dist/framework/agents/cursor-strategy.js +138 -20
  21. package/dist/framework/agents/gemini-strategy.js +34 -7
  22. package/dist/framework/agents/index.js +285 -6
  23. package/dist/framework/agents/middleware/assistant-round-pipeline.js +2 -2
  24. package/dist/framework/agents/providers/base.js +1 -1
  25. package/dist/framework/agents/providers/index.js +4 -1
  26. package/dist/framework/agents/providers/openai-transport.js +4 -2
  27. package/dist/framework/agents/providers/openai.js +1 -1
  28. package/dist/framework/agents/providers/transport-base.js +1 -1
  29. package/dist/framework/agents/utils/auth-resolver.js +1 -1
  30. package/dist/framework/agents/utils/cursor-output-formatter.js +25 -1
  31. package/dist/framework/agents/utils/openai-proxy-formatter.js +75 -5
  32. package/dist/framework/agents/utils/payload-budget.js +2 -2
  33. package/dist/framework/agents/utils/structured-output-formatter.js +8 -4
  34. package/dist/framework/code-generator.js +309 -10
  35. package/dist/framework/constants.js +1 -1
  36. package/dist/framework/context-loader.js +2 -2
  37. package/dist/framework/function-bridge.js +60 -1
  38. package/dist/framework/function-skill-registry.js +1 -1
  39. package/dist/framework/graph-compiler.js +314 -1
  40. package/dist/framework/graph.js +305 -4
  41. package/dist/framework/index.js +331 -1
  42. package/dist/framework/mcp-client.js +56 -2
  43. package/dist/framework/node-registry.js +294 -3
  44. package/dist/framework/node.js +297 -4
  45. package/dist/framework/output-parser.js +2 -2
  46. package/dist/framework/skill-registry.js +1 -1
  47. package/dist/framework/state-utils.js +5 -1
  48. package/dist/framework/state.js +1 -1
  49. package/dist/framework/tool-resolver.js +1 -1
  50. package/dist/index.js +512 -5
  51. package/dist/package.json +1 -1
  52. package/dist/runtime/generation/base.js +1 -1
  53. package/dist/runtime/generation/index.js +58 -3
  54. package/dist/runtime/generation/mcp-ref-strategy.js +17 -17
  55. package/dist/runtime/generation/stable-id-strategy.js +14 -14
  56. package/dist/runtime/stable-id-runtime.js +1 -1
  57. package/dist/runtime/verification/base.js +1 -1
  58. package/dist/runtime/verification/index.js +3 -3
  59. package/dist/runtime/verification/playwright-json-strategy.js +1 -1
  60. package/dist/runtime/zibby-runtime.js +1 -1
  61. package/dist/sync/index.js +1 -1
  62. package/dist/sync/uploader.js +1 -1
  63. package/dist/tools/run-playwright-test.js +3 -3
  64. package/dist/utils/adf-converter.js +1 -1
  65. package/dist/utils/ast-utils.js +9 -1
  66. package/dist/utils/ci-setup.js +4 -4
  67. package/dist/utils/cursor-mcp-isolated-home.js +1 -1
  68. package/dist/utils/cursor-utils.js +1 -1
  69. package/dist/utils/live-frame-discovery.js +1 -1
  70. package/dist/utils/logger.js +1 -1
  71. package/dist/utils/mcp-config-writer.js +4 -4
  72. package/dist/utils/mission-control-from-run-states.js +1 -1
  73. package/dist/utils/node-schema-parser.js +9 -1
  74. package/dist/utils/parallel-config.js +1 -1
  75. package/dist/utils/post-process-events.js +2 -1
  76. package/dist/utils/repo-clone.js +1 -0
  77. package/dist/utils/result-handler.js +1 -1
  78. package/dist/utils/ripple-effect.js +1 -1
  79. package/dist/utils/run-capacity-coordinator.js +3 -1
  80. package/dist/utils/run-capacity-queue.js +2 -2
  81. package/dist/utils/run-index-merge.js +1 -1
  82. package/dist/utils/run-index-post-cli.js +4 -1
  83. package/dist/utils/run-registry.js +3 -3
  84. package/dist/utils/run-state-session.js +2 -2
  85. package/dist/utils/selector-generator.js +4 -4
  86. package/dist/utils/session-state-constants.js +1 -1
  87. package/dist/utils/session-state-live-runs.js +1 -1
  88. package/dist/utils/streaming-parser.js +3 -3
  89. package/dist/utils/test-post-processor.js +14 -11
  90. package/dist/utils/timeline.js +6 -6
  91. package/dist/utils/trace-parser.js +2 -2
  92. package/dist/utils/video-organizer.js +3 -3
  93. package/package.json +1 -1
  94. package/templates/browser-test-automation/result-handler.mjs +4 -39
@@ -1 +1 @@
1
- import{existsSync as f,readFileSync as u}from"fs";import{homedir as l}from"os";import{join as h}from"path";const o=new Map;function w(){if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{const t=h(l(),".zibby","config.json");return f(t)&&JSON.parse(u(t,"utf-8")).sessionToken||null}catch{return null}}function k(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://account-api-prod.zibby.app"}async function y(t){const s=Date.now(),r=o.get(t);if(r&&r.expiresAt>s)return r.data;const i=w();if(!i)throw new Error("No session token. Run `zibby login` first.");const c=`${k()}/integrations/token/${t}`,n=await fetch(c,{method:"GET",headers:{Authorization:`Bearer ${i}`}});if(!n.ok){const p=await n.text().catch(()=>"");throw n.status===404?new Error(`${t} is not connected. Connect it at https://studio.zibby.app/integrations`):n.status===401||n.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${t} token (${n.status}): ${p}`)}const e=await n.json();if(!e||typeof e!="object")throw new Error(`Invalid response from ${t} token endpoint: expected object, got ${typeof e}`);if(t==="jira"){if(!e.token||typeof e.token!="string")throw new Error(`Invalid jira token response: token is ${typeof e.token}, expected string`);if(!e.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(t==="github"&&(!e.token||typeof e.token!="string"))throw new Error(`Invalid github token response: token is ${typeof e.token}, expected string`);const a=((e.expiresInSec||3e3)-120)*1e3;return o.set(t,{data:e,expiresAt:s+a}),e}function b(t){t?o.delete(t):o.clear()}export{b as clearTokenCache,y as resolveIntegrationToken};
1
+ import{existsSync as f,readFileSync as u}from"fs";import{homedir as l}from"os";import{join as h}from"path";var o=new Map;function w(){if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let t=h(l(),".zibby","config.json");return f(t)&&JSON.parse(u(t,"utf-8")).sessionToken||null}catch{return null}}function k(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://account-api-prod.zibby.app"}async function y(t){let s=Date.now(),r=o.get(t);if(r&&r.expiresAt>s)return r.data;let i=w();if(!i)throw new Error("No session token. Run `zibby login` first.");let c=`${k()}/integrations/token/${t}`,n=await fetch(c,{method:"GET",headers:{Authorization:`Bearer ${i}`}});if(!n.ok){let p=await n.text().catch(()=>"");throw n.status===404?new Error(`${t} is not connected. Connect it at https://studio.zibby.app/integrations`):n.status===401||n.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${t} token (${n.status}): ${p}`)}let e=await n.json();if(!e||typeof e!="object")throw new Error(`Invalid response from ${t} token endpoint: expected object, got ${typeof e}`);if(t==="jira"){if(!e.token||typeof e.token!="string")throw new Error(`Invalid jira token response: token is ${typeof e.token}, expected string`);if(!e.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(t==="github"&&(!e.token||typeof e.token!="string"))throw new Error(`Invalid github token response: token is ${typeof e.token}, expected string`);let a=((e.expiresInSec||3e3)-120)*1e3;return o.set(t,{data:e,expiresAt:s+a}),e}function b(t){t?o.delete(t):o.clear()}export{b as clearTokenCache,y as resolveIntegrationToken};
@@ -1 +1 @@
1
- const _={READ_FILE:"read_file",WRITE_FILE:"write_file",LIST_DIRECTORY:"list_directory",RUN_COMMAND:"run_command",OPEN_URL:"open_url",WAIT:"wait"},t={LIST_PROJECTS:"jira_list_projects",SEARCH:"jira_search",GET_ISSUE:"jira_get_issue",CREATE_ISSUE:"jira_create_issue",LIST_SPRINTS:"jira_list_sprints",GET_SPRINT_ISSUES:"jira_get_sprint_issues",GET_COMMENTS:"jira_get_comments",ADD_COMMENT:"jira_add_comment",EDIT_ISSUE:"jira_edit_issue",TRANSITION_ISSUE:"jira_transition_issue"},e={GET_USER:"github_get_user",LIST_ORGS:"github_list_orgs",LIST_REPOS:"github_list_repos",CLONE:"github_clone",SEARCH_REPOS:"github_search_repos",SEARCH_ISSUES:"github_search_issues",SEARCH_CODE:"github_search_code",GET_PR:"github_get_pr",GET_PR_DIFF:"github_get_pr_diff",LIST_PR_FILES:"github_list_pr_files",LIST_PR_COMMENTS:"github_list_pr_comments",LIST_COMMITS:"github_list_commits",GET_COMMIT:"github_get_commit",GET_FILE:"github_get_file",CREATE_ISSUE:"github_create_issue"},s={LIST_CHANNELS:"slack_list_channels",POST_MESSAGE:"slack_post_message",REPLY_TO_THREAD:"slack_reply_to_thread",ADD_REACTION:"slack_add_reaction",GET_CHANNEL_HISTORY:"slack_get_channel_history",GET_THREAD_REPLIES:"slack_get_thread_replies",GET_USERS:"slack_get_users",GET_USER_PROFILE:"slack_get_user_profile"},S={GENERATE:"run_generate",TEST:"run_test",STATUS:"run_status",CANCEL:"run_cancel",WAIT:"run_wait",ARTIFACTS:"run_artifacts",LIST_SPECS:"list_specs"},E={GET_TEST_HISTORY:"memory_get_test_history",GET_SELECTORS:"memory_get_selectors",GET_PAGE_MODEL:"memory_get_page_model",GET_NAVIGATION:"memory_get_navigation",SAVE_INSIGHT:"memory_save_insight"},T={STORE:"memory_store",RECALL:"memory_recall",BRIEF:"memory_brief",END_SESSION:"memory_end_session",TASK_LOG:"task_log",TASK_HISTORY:"task_history"},i={INSTALL:"install_skill",UNINSTALL:"uninstall_skill",LIST_AVAILABLE:"list_available_skills"},r={..._,...t,...e,...s,...S,...E,...T,...i};export{r as ALL_TOOLS,T as CHAT_MEMORY_TOOLS,_ as CORE_TOOLS,e as GITHUB_TOOLS,t as JIRA_TOOLS,E as MEMORY_TOOLS,S as RUNNER_TOOLS,i as SKILL_TOOLS,s as SLACK_TOOLS};
1
+ var _={READ_FILE:"read_file",WRITE_FILE:"write_file",LIST_DIRECTORY:"list_directory",RUN_COMMAND:"run_command",OPEN_URL:"open_url",WAIT:"wait"},t={LIST_PROJECTS:"jira_list_projects",SEARCH:"jira_search",GET_ISSUE:"jira_get_issue",CREATE_ISSUE:"jira_create_issue",LIST_SPRINTS:"jira_list_sprints",GET_SPRINT_ISSUES:"jira_get_sprint_issues",GET_COMMENTS:"jira_get_comments",ADD_COMMENT:"jira_add_comment",EDIT_ISSUE:"jira_edit_issue",TRANSITION_ISSUE:"jira_transition_issue"},e={GET_USER:"github_get_user",LIST_ORGS:"github_list_orgs",LIST_REPOS:"github_list_repos",CLONE:"github_clone",SEARCH_REPOS:"github_search_repos",SEARCH_ISSUES:"github_search_issues",SEARCH_CODE:"github_search_code",GET_PR:"github_get_pr",GET_PR_DIFF:"github_get_pr_diff",LIST_PR_FILES:"github_list_pr_files",LIST_PR_COMMENTS:"github_list_pr_comments",LIST_COMMITS:"github_list_commits",GET_COMMIT:"github_get_commit",GET_FILE:"github_get_file",CREATE_ISSUE:"github_create_issue"},s={LIST_CHANNELS:"slack_list_channels",POST_MESSAGE:"slack_post_message",REPLY_TO_THREAD:"slack_reply_to_thread",ADD_REACTION:"slack_add_reaction",GET_CHANNEL_HISTORY:"slack_get_channel_history",GET_THREAD_REPLIES:"slack_get_thread_replies",GET_USERS:"slack_get_users",GET_USER_PROFILE:"slack_get_user_profile"},S={GENERATE:"run_generate",TEST:"run_test",STATUS:"run_status",CANCEL:"run_cancel",WAIT:"run_wait",ARTIFACTS:"run_artifacts",LIST_SPECS:"list_specs"},E={GET_TEST_HISTORY:"memory_get_test_history",GET_SELECTORS:"memory_get_selectors",GET_PAGE_MODEL:"memory_get_page_model",GET_NAVIGATION:"memory_get_navigation",SAVE_INSIGHT:"memory_save_insight"},T={STORE:"memory_store",RECALL:"memory_recall",BRIEF:"memory_brief",END_SESSION:"memory_end_session",TASK_LOG:"task_log",TASK_HISTORY:"task_history"},i={INSTALL:"install_skill",UNINSTALL:"uninstall_skill",LIST_AVAILABLE:"list_available_skills"},r={..._,...t,...e,...s,...S,...E,...T,...i};export{r as ALL_TOOLS,T as CHAT_MEMORY_TOOLS,_ as CORE_TOOLS,e as GITHUB_TOOLS,t as JIRA_TOOLS,E as MEMORY_TOOLS,S as RUNNER_TOOLS,i as SKILL_TOOLS,s as SLACK_TOOLS};
@@ -1 +1 @@
1
- import{resolve as c}from"path";const t=".zibby/scratch/specs";function o(r){return c(String(r||process.cwd()),t)}export{t as ZIBBY_SCRATCH_SPECS_REL,o as zibbyScratchSpecsDir};
1
+ import{resolve as c}from"path";var t=".zibby/scratch/specs";function o(r){return c(String(r||process.cwd()),t)}export{t as ZIBBY_SCRATCH_SPECS_REL,o as zibbyScratchSpecsDir};
package/dist/constants.js CHANGED
@@ -1 +1 @@
1
- const o={ASSISTANT:"gpt-5.4-nano-2026-03-17",CLAUDE:"claude-sonnet-4-6",CURSOR:"auto",CODEX:"o4-mini",GEMINI:"gemini-2.5-pro",OPENAI_POSTPROCESSING:"gpt-4o-mini"},n={ASSISTANT:"assistant",CLAUDE:"claude",CURSOR:"cursor",CODEX:"codex",GEMINI:"gemini"},e={DEBUG:"debug",INFO:"info",WARN:"warn",ERROR:"error",SILENT:"silent"},t={auto:"claude-sonnet-4-6","sonnet-4.6":"claude-sonnet-4-6","sonnet-4-6":"claude-sonnet-4-6","opus-4.6":"claude-opus-4-6","opus-4-6":"claude-opus-4-6","sonnet-4.5":"claude-sonnet-4-5-20250929","sonnet-4-5":"claude-sonnet-4-5-20250929","opus-4.5":"claude-opus-4-20250514","opus-4-5":"claude-opus-4-20250514","claude-sonnet-4-6":"claude-sonnet-4-6","claude-opus-4-6":"claude-opus-4-6","claude-sonnet-4-5-20250929":"claude-sonnet-4-5-20250929","claude-opus-4-20250514":"claude-opus-4-20250514"},s={auto:"o4-mini","o4-mini":"o4-mini",o3:"o3","o3-mini":"o3-mini","codex-mini":"codex-mini-latest","gpt-4o":"gpt-4o","gpt-4o-mini":"gpt-4o-mini","gpt-5.2-codex":"gpt-5.2-codex","gpt-5.2":"gpt-5.2","gpt-5.3":"gpt-5.3","gpt-5.4":"gpt-5.4"},i={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},p={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};export{n as AGENT_TYPES,t as CLAUDE_MODEL_MAP,s as CODEX_MODEL_MAP,o as DEFAULT_MODELS,i as GEMINI_MODEL_MAP,e as LOG_LEVELS,p as TIMEOUTS};
1
+ var o={ASSISTANT:"gpt-5.4-nano-2026-03-17",CLAUDE:"claude-sonnet-4-6",CURSOR:"auto",CODEX:"o4-mini",GEMINI:"gemini-2.5-pro",OPENAI_POSTPROCESSING:"gpt-4o-mini"},n={ASSISTANT:"assistant",CLAUDE:"claude",CURSOR:"cursor",CODEX:"codex",GEMINI:"gemini"},e={DEBUG:"debug",INFO:"info",WARN:"warn",ERROR:"error",SILENT:"silent"},t={auto:"claude-sonnet-4-6","sonnet-4.6":"claude-sonnet-4-6","sonnet-4-6":"claude-sonnet-4-6","opus-4.6":"claude-opus-4-6","opus-4-6":"claude-opus-4-6","sonnet-4.5":"claude-sonnet-4-5-20250929","sonnet-4-5":"claude-sonnet-4-5-20250929","opus-4.5":"claude-opus-4-20250514","opus-4-5":"claude-opus-4-20250514","claude-sonnet-4-6":"claude-sonnet-4-6","claude-opus-4-6":"claude-opus-4-6","claude-sonnet-4-5-20250929":"claude-sonnet-4-5-20250929","claude-opus-4-20250514":"claude-opus-4-20250514"},s={auto:"o4-mini","o4-mini":"o4-mini",o3:"o3","o3-mini":"o3-mini","codex-mini":"codex-mini-latest","gpt-4o":"gpt-4o","gpt-4o-mini":"gpt-4o-mini","gpt-5.2-codex":"gpt-5.2-codex","gpt-5.2":"gpt-5.2","gpt-5.3":"gpt-5.3","gpt-5.4":"gpt-5.4"},i={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},p={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};export{n as AGENT_TYPES,t as CLAUDE_MODEL_MAP,s as CODEX_MODEL_MAP,o as DEFAULT_MODELS,i as GEMINI_MODEL_MAP,e as LOG_LEVELS,p as TIMEOUTS};
@@ -1 +1 @@
1
- class t{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,r){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,r){return console.warn(`[${this.getName()}] Enrichment failed for event ${r.type}:`,e.message),null}}var i=t;export{t as EventEnricher,i as default};
1
+ var t=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,r){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,r){return console.warn(`[${this.getName()}] Enrichment failed for event ${r.type}:`,e.message),null}},i=t;export{t as EventEnricher,i as default};
@@ -1 +1 @@
1
- import{EventEnricher as o}from"../base.js";import s from"crypto";class u extends o{getName(){return"AccessibilityEnricher"}getPriority(){return 100}canEnrich(t){return!this.enabled||!t.element||!t.event?!1:["click","fill","type","selectOption","hover"].includes(t.event.type)}async enrich(t,r){try{const{page:e,element:i}=r,n=await e.accessibility.snapshot(),a=await this.findAxNode(i,n);if(!a)return null;const l=await this.getAxContext(a,n),h=this.hashAxSubtree(a),c=this.hashAxPath(l.path);return{accessibility:{role:a.role,name:a.name||"",level:l.level,parent:l.parent,siblings:l.siblings,axTreeHash:h,axPathHash:c}}}catch(e){return this.handleError(e,t)}}async findAxNode(t,r){const e=await t.evaluate(i=>({role:i.getAttribute("role")||i.tagName.toLowerCase(),name:i.getAttribute("aria-label")||i.textContent?.trim()||"",tagName:i.tagName.toLowerCase()}));return this.searchAxTree(r,e)}searchAxTree(t,r){if(!t)return null;if(t.role===r.role&&(t.name||"").includes(r.name.substring(0,20)))return t;if(t.children)for(const e of t.children){const i=this.searchAxTree(e,r);if(i)return i}return null}getAxContext(t,r){const e={level:0,parent:null,siblings:[],path:[]},i=this.findParent(t,r);return i&&(e.parent={role:i.role,name:i.name},e.siblings=(i.children||[]).filter(n=>n!==t).map(n=>({role:n.role,name:n.name})).slice(0,3)),e.level=this.calculateLevel(t,r),e.path=this.buildPath(t,r),e}findParent(t,r,e=r){if(!e||!e.children)return null;if(e.children.includes(t))return e;for(const i of e.children){const n=this.findParent(t,r,i);if(n)return n}return null}calculateLevel(t,r,e=r,i=0){if(e===t)return i;if(e.children)for(const n of e.children){const a=this.calculateLevel(t,r,n,i+1);if(a>=0)return a}return-1}buildPath(t,r,e=r,i=[]){if(e===t)return[...i,{role:e.role,name:e.name}];if(e.children)for(const n of e.children){const a=this.buildPath(t,r,n,[...i,{role:e.role,name:e.name}]);if(a)return a}return null}hashAxSubtree(t){const r=JSON.stringify({role:t.role,name:t.name,children:(t.children||[]).map(e=>({role:e.role,name:e.name}))});return s.createHash("md5").update(r).digest("hex").substring(0,12)}hashAxPath(t){const r=t.map(e=>`${e.role}:${e.name}`).join("/");return s.createHash("md5").update(r).digest("hex").substring(0,12)}}var x=u;export{u as AccessibilityEnricher,x as default};
1
+ var s=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,r){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,r){return console.warn(`[${this.getName()}] Enrichment failed for event ${r.type}:`,e.message),null}};import o from"crypto";var h=class extends s{getName(){return"AccessibilityEnricher"}getPriority(){return 100}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,r){try{let{page:t,element:n}=r,i=await t.accessibility.snapshot(),a=await this.findAxNode(n,i);if(!a)return null;let l=await this.getAxContext(a,i),u=this.hashAxSubtree(a),f=this.hashAxPath(l.path);return{accessibility:{role:a.role,name:a.name||"",level:l.level,parent:l.parent,siblings:l.siblings,axTreeHash:u,axPathHash:f}}}catch(t){return this.handleError(t,e)}}async findAxNode(e,r){let t=await e.evaluate(n=>({role:n.getAttribute("role")||n.tagName.toLowerCase(),name:n.getAttribute("aria-label")||n.textContent?.trim()||"",tagName:n.tagName.toLowerCase()}));return this.searchAxTree(r,t)}searchAxTree(e,r){if(!e)return null;if(e.role===r.role&&(e.name||"").includes(r.name.substring(0,20)))return e;if(e.children)for(let t of e.children){let n=this.searchAxTree(t,r);if(n)return n}return null}getAxContext(e,r){let t={level:0,parent:null,siblings:[],path:[]},n=this.findParent(e,r);return n&&(t.parent={role:n.role,name:n.name},t.siblings=(n.children||[]).filter(i=>i!==e).map(i=>({role:i.role,name:i.name})).slice(0,3)),t.level=this.calculateLevel(e,r),t.path=this.buildPath(e,r),t}findParent(e,r,t=r){if(!t||!t.children)return null;if(t.children.includes(e))return t;for(let n of t.children){let i=this.findParent(e,r,n);if(i)return i}return null}calculateLevel(e,r,t=r,n=0){if(t===e)return n;if(t.children)for(let i of t.children){let a=this.calculateLevel(e,r,i,n+1);if(a>=0)return a}return-1}buildPath(e,r,t=r,n=[]){if(t===e)return[...n,{role:t.role,name:t.name}];if(t.children)for(let i of t.children){let a=this.buildPath(e,r,i,[...n,{role:t.role,name:t.name}]);if(a)return a}return null}hashAxSubtree(e){let r=JSON.stringify({role:e.role,name:e.name,children:(e.children||[]).map(t=>({role:t.role,name:t.name}))});return o.createHash("md5").update(r).digest("hex").substring(0,12)}hashAxPath(e){let r=e.map(t=>`${t.role}:${t.name}`).join("/");return o.createHash("md5").update(r).digest("hex").substring(0,12)}},p=h;export{h as AccessibilityEnricher,p as default};
@@ -1 +1 @@
1
- import{EventEnricher as v}from"../base.js";class E extends v{getName(){return"DOMEnricher"}getPriority(){return 85}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,a){try{const{element:s}=a,r=await s.evaluate(i=>{const f=o=>{const c=[];let t=o;for(;t&&t!==document.body;){let p=t.tagName.toLowerCase();const n=t.parentElement;if(n){const u=Array.from(n.children).filter(h=>h.tagName===t.tagName);if(u.length>1){const h=u.indexOf(t)+1;p+=`:nth-child(${h})`}}c.unshift(p),t=t.parentElement}return`body > ${c.join(" > ")}`},g=o=>{const c=[];let t=o;for(;t&&t!==document.body;){let p=1,n=t.previousSibling;for(;n;)n.nodeType===1&&n.tagName===t.tagName&&p++,n=n.previousSibling;const u=t.tagName.toLowerCase();c.unshift(`${u}[${p}]`),t=t.parentElement}return`/html/body/${c.join("/")}`},b={};for(const o of i.attributes)b[o.name]=o.value;const l=window.getComputedStyle(i),y={display:l.display,visibility:l.visibility,opacity:l.opacity,pointerEvents:l.pointerEvents};let m=0,d=i.parentElement;for(;d;)m++,d=d.parentElement;return{path:f(i),xpath:g(i),depth:m,parent:i.parentElement?i.parentElement.tagName.toLowerCase():null,tagName:i.tagName.toLowerCase(),attributes:b,state:{visible:l.display!=="none"&&l.visibility!=="hidden",enabled:!i.disabled,focused:document.activeElement===i,...y}}});return{dom:{path:r.path,xpath:r.xpath,depth:r.depth,parent:r.parent,selector:this.buildSmartSelector(r)},attributes:r.attributes,state:r.state}}catch(s){return this.handleError(s,e)}}buildSmartSelector(e){let a=e.tagName;if(e.attributes.id)return`#${e.attributes.id}`;if(e.attributes["data-test-id"])return`[data-test-id="${e.attributes["data-test-id"]}"]`;if(e.attributes.class){const s=e.attributes.class.split(" ").filter(r=>r&&!r.match(/^(active|focus|hover|disabled)/));s.length>0&&(a+=`.${s.slice(0,2).join(".")}`)}return e.parent&&(a=`${e.parent} > ${a}`),a}}var $=E;export{E as DOMEnricher,$ as default};
1
+ var h=class{constructor(t={}){this.config=t,this.enabled=t.enabled!==!1,this.priority=t.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(t){return this.enabled}async enrich(t,i){throw new Error("EventEnricher.enrich() must be implemented")}handleError(t,i){return console.warn(`[${this.getName()}] Enrichment failed for event ${i.type}:`,t.message),null}};var b=class extends h{getName(){return"DOMEnricher"}getPriority(){return 85}canEnrich(t){return!this.enabled||!t.element||!t.event?!1:["click","fill","type","selectOption","hover"].includes(t.event.type)}async enrich(t,i){try{let{element:s}=i,r=await s.evaluate(n=>{let E=o=>{let c=[],e=o;for(;e&&e!==document.body;){let p=e.tagName.toLowerCase(),a=e.parentElement;if(a){let u=Array.from(a.children).filter(m=>m.tagName===e.tagName);if(u.length>1){let m=u.indexOf(e)+1;p+=`:nth-child(${m})`}}c.unshift(p),e=e.parentElement}return`body > ${c.join(" > ")}`},v=o=>{let c=[],e=o;for(;e&&e!==document.body;){let p=1,a=e.previousSibling;for(;a;)a.nodeType===1&&a.tagName===e.tagName&&p++,a=a.previousSibling;let u=e.tagName.toLowerCase();c.unshift(`${u}[${p}]`),e=e.parentElement}return`/html/body/${c.join("/")}`},f={};for(let o of n.attributes)f[o.name]=o.value;let l=window.getComputedStyle(n),w={display:l.display,visibility:l.visibility,opacity:l.opacity,pointerEvents:l.pointerEvents},g=0,d=n.parentElement;for(;d;)g++,d=d.parentElement;return{path:E(n),xpath:v(n),depth:g,parent:n.parentElement?n.parentElement.tagName.toLowerCase():null,tagName:n.tagName.toLowerCase(),attributes:f,state:{visible:l.display!=="none"&&l.visibility!=="hidden",enabled:!n.disabled,focused:document.activeElement===n,...w}}});return{dom:{path:r.path,xpath:r.xpath,depth:r.depth,parent:r.parent,selector:this.buildSmartSelector(r)},attributes:r.attributes,state:r.state}}catch(s){return this.handleError(s,t)}}buildSmartSelector(t){let i=t.tagName;if(t.attributes.id)return`#${t.attributes.id}`;if(t.attributes["data-test-id"])return`[data-test-id="${t.attributes["data-test-id"]}"]`;if(t.attributes.class){let s=t.attributes.class.split(" ").filter(r=>r&&!r.match(/^(active|focus|hover|disabled)/));s.length>0&&(i+=`.${s.slice(0,2).join(".")}`)}return t.parent&&(i=`${t.parent} > ${i}`),i}},x=b;export{b as DOMEnricher,x as default};
@@ -1 +1 @@
1
- import{EventEnricher as c}from"../base.js";class o extends c{constructor(e={}){super(e),this.pendingRequests=new Set,this.setupNetworkTracking=!1}getName(){return"PageStateEnricher"}getPriority(){return 95}canEnrich(e){return this.enabled&&e.page}async setupTracking(e){this.setupNetworkTracking||(e.on("request",t=>{["document","xhr","fetch"].includes(t.resourceType())&&this.pendingRequests.add(t.url())}),e.on("requestfinished",t=>{this.pendingRequests.delete(t.url())}),e.on("requestfailed",t=>{this.pendingRequests.delete(t.url())}),this.setupNetworkTracking=!0)}async enrich(e,t){try{const{page:r}=t;await this.setupTracking(r);const n=await r.evaluate(()=>({readyState:document.readyState,domContentLoaded:document.readyState!=="loading",loadComplete:document.readyState==="complete",url:document.location.href})),s=await this.checkDOMStability(r);return{page:{networkIdle:this.pendingRequests.size===0,pendingRequests:this.pendingRequests.size,domStable:s,...n}}}catch(r){return this.handleError(r,e)}}async checkDOMStability(e,t=500){try{return await e.evaluate(n=>new Promise(s=>{let i,u=0;const a=new MutationObserver(()=>{u++,clearTimeout(i),i=setTimeout(()=>{a.disconnect(),s(u===0)},n)});a.observe(document.body,{childList:!0,subtree:!0,attributes:!0}),i=setTimeout(()=>{a.disconnect(),s(!0)},n)}),t)}catch{return!1}}reset(){this.pendingRequests.clear(),this.setupNetworkTracking=!1}}var h=o;export{o as PageStateEnricher,h as default};
1
+ var i=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,t){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,t){return console.warn(`[${this.getName()}] Enrichment failed for event ${t.type}:`,e.message),null}};var u=class extends i{constructor(e={}){super(e),this.pendingRequests=new Set,this.setupNetworkTracking=!1}getName(){return"PageStateEnricher"}getPriority(){return 95}canEnrich(e){return this.enabled&&e.page}async setupTracking(e){this.setupNetworkTracking||(e.on("request",t=>{["document","xhr","fetch"].includes(t.resourceType())&&this.pendingRequests.add(t.url())}),e.on("requestfinished",t=>{this.pendingRequests.delete(t.url())}),e.on("requestfailed",t=>{this.pendingRequests.delete(t.url())}),this.setupNetworkTracking=!0)}async enrich(e,t){try{let{page:r}=t;await this.setupTracking(r);let n=await r.evaluate(()=>({readyState:document.readyState,domContentLoaded:document.readyState!=="loading",loadComplete:document.readyState==="complete",url:document.location.href})),s=await this.checkDOMStability(r);return{page:{networkIdle:this.pendingRequests.size===0,pendingRequests:this.pendingRequests.size,domStable:s,...n}}}catch(r){return this.handleError(r,e)}}async checkDOMStability(e,t=500){try{return await e.evaluate(n=>new Promise(s=>{let a,c=0,o=new MutationObserver(()=>{c++,clearTimeout(a),a=setTimeout(()=>{o.disconnect(),s(c===0)},n)});o.observe(document.body,{childList:!0,subtree:!0,attributes:!0}),a=setTimeout(()=>{o.disconnect(),s(!0)},n)}),t)}catch{return!1}}reset(){this.pendingRequests.clear(),this.setupNetworkTracking=!1}},p=u;export{u as PageStateEnricher,p as default};
@@ -1 +1 @@
1
- import{EventEnricher as h}from"../base.js";class s extends h{getName(){return"PositionEnricher"}getPriority(){return 90}canEnrich(r){return!this.enabled||!r.element||!r.event?!1:["click","fill","type","selectOption","hover"].includes(r.event.type)}async enrich(r,i){try{const{page:n,element:o}=i,e=await o.boundingBox();if(!e)return null;const t=await n.evaluate(()=>({scrollX:window.scrollX,scrollY:window.scrollY,width:window.innerWidth,height:window.innerHeight})),l=e.y>=t.scrollY&&e.y+e.height<=t.scrollY+t.height&&e.x>=0&&e.x+e.width<=t.width;return{position:{boundingBox:e,viewport:t,inViewport:l,centerPoint:{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}}}catch(n){return this.handleError(n,r)}}}var d=s;export{s as PositionEnricher,d as default};
1
+ var i=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,n){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,n){return console.warn(`[${this.getName()}] Enrichment failed for event ${n.type}:`,e.message),null}};var l=class extends i{getName(){return"PositionEnricher"}getPriority(){return 90}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,n){try{let{page:o,element:s}=n,t=await s.boundingBox();if(!t)return null;let r=await o.evaluate(()=>({scrollX:window.scrollX,scrollY:window.scrollY,width:window.innerWidth,height:window.innerHeight})),a=t.y>=r.scrollY&&t.y+t.height<=r.scrollY+r.height&&t.x>=0&&t.x+t.width<=r.width;return{position:{boundingBox:t,viewport:r,inViewport:a,centerPoint:{x:Math.round(t.x+t.width/2),y:Math.round(t.y+t.height/2)}}}}catch(o){return this.handleError(o,e)}}},u=l;export{l as PositionEnricher,u as default};
@@ -1 +1,4 @@
1
- import{EventEnricher as D}from"./base.js";import{EnrichmentPipeline as A}from"./pipeline.js";import{PositionEnricher as R}from"./enrichers/position-enricher.js";import{AccessibilityEnricher as v}from"./enrichers/accessibility-enricher.js";import{PageStateEnricher as j}from"./enrichers/page-state-enricher.js";import{DOMEnricher as q}from"./enrichers/dom-enricher.js";import{MCPRefEnricher as B}from"./mcp-ref-enricher.js";import{TraceTextEnricher as G}from"./trace-text-enricher.js";import{EnrichmentPipeline as i}from"./pipeline.js";import{PositionEnricher as s}from"./enrichers/position-enricher.js";import{AccessibilityEnricher as n}from"./enrichers/accessibility-enricher.js";import{PageStateEnricher as o}from"./enrichers/page-state-enricher.js";import{DOMEnricher as a}from"./enrichers/dom-enricher.js";import{MCPRefEnricher as m}from"./mcp-ref-enricher.js";import{TraceTextEnricher as l}from"./trace-text-enricher.js";function b(e={}){const r=new i(e);return e.enableMCPRef!==!1&&r.register(new m(e)),e.enableTraceText!==!1&&r.register(new l(e)),e.enableAccessibility!==!1&&r.register(new n(e)),e.enablePageState!==!1&&r.register(new o(e)),e.enablePosition!==!1&&r.register(new s(e)),e.enableDOM!==!1&&r.register(new a(e)),r}function u(e={}){const r=new i(e);return r.register(new n(e)),r.register(new o(e)),r}function M(e,r={}){const t=new i(r);for(const p of e)t.register(p);return t}export{v as AccessibilityEnricher,q as DOMEnricher,A as EnrichmentPipeline,D as EventEnricher,B as MCPRefEnricher,j as PageStateEnricher,R as PositionEnricher,G as TraceTextEnricher,M as createCustomPipeline,b as createDefaultPipeline,u as createMinimalPipeline};
1
+ var g=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,r){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,r){return console.warn(`[${this.getName()}] Enrichment failed for event ${r.type}:`,e.message),null}};var S=class{constructor(e={}){this.enrichers=[],this.config=e,this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}register(e){return this.enrichers.push(e),this.enrichers.sort((r,t)=>t.getPriority()-r.getPriority()),this}unregister(e){return this.enrichers=this.enrichers.filter(r=>r.getName()!==e),this}get(e){return this.enrichers.find(r=>r.getName()===e)}setEnabled(e,r){let t=this.get(e);return t&&(t.enabled=r),this}async enrich(e,r){this.stats.totalEvents++;let t={...e},i=[],n=[],s=[];for(let o of this.enrichers)try{if(!o.canEnrich(r)){n.push(o.getName());continue}let l=Date.now(),a=await o.enrich(e,r),f=Date.now()-l;a?(Object.assign(t,a),i.push({name:o.getName(),duration:f})):n.push(o.getName())}catch(l){console.warn(`[EnrichmentPipeline] ${o.getName()} failed:`,l.message),s.push(o.getName()),this.stats.errors[o.getName()]=(this.stats.errors[o.getName()]||0)+1}return t._enrichment={version:"1.0",timestamp:new Date().toISOString(),enrichers:{run:i,skipped:n,failed:s}},i.length>0?this.stats.enrichedEvents++:this.stats.skippedEvents++,t}async enrichBatch(e,r){let t=[];for(let i of e){let n=await this.enrich(i,r);t.push(n)}return t}getStats(){return{...this.stats,enrichers:this.enrichers.map(e=>({name:e.getName(),enabled:e.enabled,priority:e.getPriority(),errors:this.stats.errors[e.getName()]||0}))}}resetStats(){this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}logStatus(){console.log(`
2
+ \u{1F4CA} Enrichment Pipeline Status:`),console.log(` Total events: ${this.stats.totalEvents}`),console.log(` Enriched: ${this.stats.enrichedEvents}`),console.log(` Skipped: ${this.stats.skippedEvents}`),console.log(`
3
+ Registered enrichers (${this.enrichers.length}):`);for(let e of this.enrichers){let r=e.enabled?"\u2713":"\u2717",t=this.stats.errors[e.getName()]||0,i=t>0?` (${t} errors)`:"";console.log(` ${r} ${e.getName()} (priority: ${e.getPriority()})${i}`)}console.log()}};var R=class extends g{getName(){return"PositionEnricher"}getPriority(){return 90}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,r){try{let{page:t,element:i}=r,n=await i.boundingBox();if(!n)return null;let s=await t.evaluate(()=>({scrollX:window.scrollX,scrollY:window.scrollY,width:window.innerWidth,height:window.innerHeight})),o=n.y>=s.scrollY&&n.y+n.height<=s.scrollY+s.height&&n.x>=0&&n.x+n.width<=s.width;return{position:{boundingBox:n,viewport:s,inViewport:o,centerPoint:{x:Math.round(n.x+n.width/2),y:Math.round(n.y+n.height/2)}}}}catch(t){return this.handleError(t,e)}}};import _ from"crypto";var P=class extends g{getName(){return"AccessibilityEnricher"}getPriority(){return 100}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,r){try{let{page:t,element:i}=r,n=await t.accessibility.snapshot(),s=await this.findAxNode(i,n);if(!s)return null;let o=await this.getAxContext(s,n),l=this.hashAxSubtree(s),a=this.hashAxPath(o.path);return{accessibility:{role:s.role,name:s.name||"",level:o.level,parent:o.parent,siblings:o.siblings,axTreeHash:l,axPathHash:a}}}catch(t){return this.handleError(t,e)}}async findAxNode(e,r){let t=await e.evaluate(i=>({role:i.getAttribute("role")||i.tagName.toLowerCase(),name:i.getAttribute("aria-label")||i.textContent?.trim()||"",tagName:i.tagName.toLowerCase()}));return this.searchAxTree(r,t)}searchAxTree(e,r){if(!e)return null;if(e.role===r.role&&(e.name||"").includes(r.name.substring(0,20)))return e;if(e.children)for(let t of e.children){let i=this.searchAxTree(t,r);if(i)return i}return null}getAxContext(e,r){let t={level:0,parent:null,siblings:[],path:[]},i=this.findParent(e,r);return i&&(t.parent={role:i.role,name:i.name},t.siblings=(i.children||[]).filter(n=>n!==e).map(n=>({role:n.role,name:n.name})).slice(0,3)),t.level=this.calculateLevel(e,r),t.path=this.buildPath(e,r),t}findParent(e,r,t=r){if(!t||!t.children)return null;if(t.children.includes(e))return t;for(let i of t.children){let n=this.findParent(e,r,i);if(n)return n}return null}calculateLevel(e,r,t=r,i=0){if(t===e)return i;if(t.children)for(let n of t.children){let s=this.calculateLevel(e,r,n,i+1);if(s>=0)return s}return-1}buildPath(e,r,t=r,i=[]){if(t===e)return[...i,{role:t.role,name:t.name}];if(t.children)for(let n of t.children){let s=this.buildPath(e,r,n,[...i,{role:t.role,name:t.name}]);if(s)return s}return null}hashAxSubtree(e){let r=JSON.stringify({role:e.role,name:e.name,children:(e.children||[]).map(t=>({role:t.role,name:t.name}))});return _.createHash("md5").update(r).digest("hex").substring(0,12)}hashAxPath(e){let r=e.map(t=>`${t.role}:${t.name}`).join("/");return _.createHash("md5").update(r).digest("hex").substring(0,12)}};var M=class extends g{constructor(e={}){super(e),this.pendingRequests=new Set,this.setupNetworkTracking=!1}getName(){return"PageStateEnricher"}getPriority(){return 95}canEnrich(e){return this.enabled&&e.page}async setupTracking(e){this.setupNetworkTracking||(e.on("request",r=>{["document","xhr","fetch"].includes(r.resourceType())&&this.pendingRequests.add(r.url())}),e.on("requestfinished",r=>{this.pendingRequests.delete(r.url())}),e.on("requestfailed",r=>{this.pendingRequests.delete(r.url())}),this.setupNetworkTracking=!0)}async enrich(e,r){try{let{page:t}=r;await this.setupTracking(t);let i=await t.evaluate(()=>({readyState:document.readyState,domContentLoaded:document.readyState!=="loading",loadComplete:document.readyState==="complete",url:document.location.href})),n=await this.checkDOMStability(t);return{page:{networkIdle:this.pendingRequests.size===0,pendingRequests:this.pendingRequests.size,domStable:n,...i}}}catch(t){return this.handleError(t,e)}}async checkDOMStability(e,r=500){try{return await e.evaluate(i=>new Promise(n=>{let s,o=0,l=new MutationObserver(()=>{o++,clearTimeout(s),s=setTimeout(()=>{l.disconnect(),n(o===0)},i)});l.observe(document.body,{childList:!0,subtree:!0,attributes:!0}),s=setTimeout(()=>{l.disconnect(),n(!0)},i)}),r)}catch{return!1}}reset(){this.pendingRequests.clear(),this.setupNetworkTracking=!1}};var k=class extends g{getName(){return"DOMEnricher"}getPriority(){return 85}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,r){try{let{element:t}=r,i=await t.evaluate(n=>{let s=c=>{let d=[],u=c;for(;u&&u!==document.body;){let x=u.tagName.toLowerCase(),b=u.parentElement;if(b){let y=Array.from(b.children).filter(T=>T.tagName===u.tagName);if(y.length>1){let T=y.indexOf(u)+1;x+=`:nth-child(${T})`}}d.unshift(x),u=u.parentElement}return`body > ${d.join(" > ")}`},o=c=>{let d=[],u=c;for(;u&&u!==document.body;){let x=1,b=u.previousSibling;for(;b;)b.nodeType===1&&b.tagName===u.tagName&&x++,b=b.previousSibling;let y=u.tagName.toLowerCase();d.unshift(`${y}[${x}]`),u=u.parentElement}return`/html/body/${d.join("/")}`},l={};for(let c of n.attributes)l[c.name]=c.value;let a=window.getComputedStyle(n),f={display:a.display,visibility:a.visibility,opacity:a.opacity,pointerEvents:a.pointerEvents},m=0,w=n.parentElement;for(;w;)m++,w=w.parentElement;return{path:s(n),xpath:o(n),depth:m,parent:n.parentElement?n.parentElement.tagName.toLowerCase():null,tagName:n.tagName.toLowerCase(),attributes:l,state:{visible:a.display!=="none"&&a.visibility!=="hidden",enabled:!n.disabled,focused:document.activeElement===n,...f}}});return{dom:{path:i.path,xpath:i.xpath,depth:i.depth,parent:i.parent,selector:this.buildSmartSelector(i)},attributes:i.attributes,state:i.state}}catch(t){return this.handleError(t,e)}}buildSmartSelector(e){let r=e.tagName;if(e.attributes.id)return`#${e.attributes.id}`;if(e.attributes["data-test-id"])return`[data-test-id="${e.attributes["data-test-id"]}"]`;if(e.attributes.class){let t=e.attributes.class.split(" ").filter(i=>i&&!i.match(/^(active|focus|hover|disabled)/));t.length>0&&(r+=`.${t.slice(0,2).join(".")}`)}return e.parent&&(r=`${e.parent} > ${r}`),r}};var L=class extends g{constructor(e={}){super(e),this.priority=200}getName(){return"MCPRef"}getPriority(){return this.priority}async enrich(e,r){let t=e.data?.params?.ref,i=e.data?.params?.element;if(!t&&!i)return null;let n=null,s=null,o=null;if(r?.element)try{let l=await r.element.evaluate(a=>({text:a.textContent?.trim()||"",innerText:a.innerText?.trim()||"",value:a.value||"",label:a.getAttribute("aria-label")||a.getAttribute("label")||"",role:a.getAttribute("role")||a.tagName.toLowerCase(),placeholder:a.getAttribute("placeholder")||"",title:a.getAttribute("title")||""}));n=l.text||l.innerText||l.value||l.placeholder,s=l.role,o=l.label||l.title,console.log(`[MCPRefEnricher] \u2705 Captured actual text: "${n}" (AI said: "${i}")`)}catch(l){console.log(`[MCPRefEnricher] \u26A0\uFE0F Could not extract actual text: ${l.message}`)}return{mcpRef:t,mcpElement:i,actualText:n,actualRole:s,actualLabel:o,recordedSelector:n||i}}};import{readFileSync as X,existsSync as I,readdirSync as H}from"fs";import{join as j}from"path";import{execSync as Z}from"child_process";import{tmpdir as K}from"os";var z=class{static async parseTraceZip(e){let r;if(e.endsWith(".zip")&&I(e)){let t=j(K(),`trace-${Date.now()}`);Z(`unzip -q "${e}" -d "${t}"`,{stdio:"pipe"});let n=H(t).find(s=>s.endsWith(".trace"));if(!n)throw new Error("No .trace file found in zip");r=j(t,n)}else if(I(e)){let i=H(e).find(n=>n.endsWith(".trace"));if(!i)throw new Error("No .trace file found");r=j(e,i)}else throw new Error(`Trace not found at ${e}`);try{let i=X(r,"utf-8").trim().split(`
4
+ `),n=[],s=new Map,o=new Map;for(let l of i)try{let a=JSON.parse(l);if(a.type==="snapshot"&&a.snapshot&&a.snapshot.accessibility){let f=new Map;for(let m of a.snapshot.accessibility)m.ref&&f.set(m.ref,m);s.set(a.snapshotName,f)}if(a.type==="frame-snapshot"&&a.snapshot){let f=Buffer.from(a.snapshot.html||"","base64").toString("utf-8");f&&f.length>100&&o.set(a.pageId||"default",f)}}catch{}for(let l of i)try{let a=JSON.parse(l);if(a.type==="before"&&a.params&&a.params.selector){let f=a.method;if(["click","fill","type","selectOption"].includes(f)){let m=a.params.selector,w=a.params.text||a.params.value||"",c=[],d=null,u=null,x=null,b=m.match(/aria-ref=([a-z0-9]+)/i);if(b&&a.snapshotName){let p=b[1],E=s.get(a.snapshotName);if(E&&E.has(p)){let v=E.get(p);d=v.name||null,u=v.role||null,x=v.label||null,console.log(`[TraceParser] \u2705 Found ACTUAL element data: text="${d}", role="${u}"`)}}let y=m.match(/internal:text="([^"]+)"/i),T=m.match(/internal:label="([^"]+)"/i),F=m.match(/internal:placeholder="([^"]+)"/i),D=m.match(/internal:role=([^ ]+)/i),A=m.match(/internal:describe="([^"]+)"/i),B=m.match(/name="([^"]+)"/i);if(y){c.push({type:"text",text:y[1]});let p=y[1].split(" ");p.length>1&&(c.push({type:"text",text:p[0],fuzzy:!0}),c.push({type:"text",text:p[p.length-1],fuzzy:!0}))}if(T&&c.push({type:"label",label:T[1]}),F&&c.push({type:"placeholder",placeholder:F[1]}),d){c.unshift({type:"text",text:d,source:"accessibility-tree"});let p=d.split(" ");p.length>1&&c.push({type:"text",text:p[0],fuzzy:!0,source:"accessibility-tree"})}if(u||D){let p=u||D[1],E=d||(B?B[1]:y?y[1]:null);c.unshift({type:"role",role:p,name:E,source:d?"accessibility-tree":"selector"})}if(x&&c.unshift({type:"label",label:x,source:"accessibility-tree"}),A){let p=A[1],E=["link","button","textbox","menuitem","submenu","combobox","checkbox","radio","tab","treeitem","menu item"],v=null,C=p;for(let N of E)if(p.toLowerCase().endsWith(` ${N}`)){v=N.replace(" ",""),C=p.substring(0,p.length-N.length-1);break}if(v){c.push({type:"role",role:v,name:C});let N=C.replace(/\s*\([^)]+\)\s*$/,"");c.push({type:"text",text:N}),c.push({type:"text",text:C});let q=C.split(" ");q.length>1&&(c.push({type:"text",text:q[0],fuzzy:!0}),c.push({type:"text",text:q.slice(0,2).join(" "),fuzzy:!0}))}else{let N=p.replace(/\s*\([^)]+\)\s*$/,"");c.push({type:"text",text:N}),c.push({type:"text",text:p})}}let Y=this.extractDOMStrategies(m,o,y?.[1]||A?.[1],a.pageId);c.push(...Y);let $=this.extractStructuralContext(m);($.parent||$.sibling)&&c.forEach(p=>{["role","text","label","testid"].includes(p.type)&&($.parent&&(p.parent=$.parent),$.sibling&&(p.sibling=$.sibling))}),c.push({type:"css",value:m});let J=d||y?y[1]:A?A[1].replace(/\s*\([^)]+\)\s*$/,""):`Action ${n.length}`;n.push({method:f,name:J,action:f==="type"?"fill":f,value:w,strategies:c,timestamp:a.startTime,actualText:d,actualRole:u,actualAriaLabel:x})}}}catch{}return n}catch(t){throw new Error(`Failed to parse trace: ${t.message}`,{cause:t})}}static extractDOMStrategies(e,r,t,i){let n=[];if(!r||r.size===0||!t)return n;try{let s=r.get(i);if(!s)return n;let o=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),l=new RegExp(`data-testid=["']([^"']+)["'][^>]*>[^<]*${o}`,"i"),a=s.match(l);a&&n.push({type:"testid",value:a[1],priority:"high"});let f=new RegExp(`class=["']([^"']+)["'][^>]*>[^<]*${o}`,"gi"),m=s.matchAll(f);for(let d of m){let u=d[1].split(/\s+/).filter(x=>x&&!x.match(/^(css|jss|makeStyles|MuiBox|MuiStack)-\w+/)&&x.length>2);u.length>0&&(n.push({type:"class",value:u.join("."),priority:"medium"}),u.length===1&&n.push({type:"class",value:u[0],priority:"medium"}))}let w=new RegExp(`id=["']([^"']+)["'][^>]*>[^<]*${o}`,"i"),c=s.match(w);c&&!c[1].match(/^(root|app|\d+|[a-f0-9-]{20,})$/i)&&n.push({type:"id",value:c[1],priority:"high"})}catch(s){console.warn(`[TraceParser] DOM extraction failed: ${s.message}`)}return n}static extractStructuralContext(e){let r={parent:null,sibling:null},t=e.split(">>").map(s=>s.trim());if(t.length>1){let o=t[t.length-2].replace(/internal:text="[^"]+"\s*/gi,"").replace(/internal:role=\S+\s*/gi,"").replace(/internal:label="[^"]+"\s*/gi,"").trim();o&&(o.match(/^(form|section|nav|header|aside|main|article)\b/)||o.includes("[")||o.match(/[#.]\w/))&&(r.parent=o)}let n=t[t.length-1].match(/([^+~]+)\s*[+~]\s*(.+)/);return n&&(r.sibling=n[1].trim()),r}};import{existsSync as U}from"fs";import{join as W}from"path";var O=class extends g{constructor(e={}){super(e),this.priority=190,this.traceData=null}getName(){return"TraceText"}getPriority(){return this.priority}async loadTrace(e){if(this.traceData)return;let r=W(e,"traces"),t=W(e,"trace.zip");if(U(t))try{this.traceData=await z.parseTraceZip(t),console.log(`[TraceTextEnricher] \u2705 Loaded trace with ${this.traceData.length} actions`)}catch(i){console.log(`[TraceTextEnricher] \u26A0\uFE0F Failed to parse trace: ${i.message}`)}}async enrich(e,r){let t=e.data?.params?.ref,i=e.id;if(t===void 0&&i===void 0||(!this.traceData&&r.sessionPath&&await this.loadTrace(r.sessionPath),!this.traceData))return null;let n=this.traceData[i];if(!n)return console.log(`[TraceTextEnricher] \u26A0\uFE0F No trace action for event ${i}`),null;let s=n.actualText||this._extractTextFromSelector(n.selector),o=n.actualRole,l=n.actualAriaLabel;return s||o||l?(console.log(`[TraceTextEnricher] \u2705 Event ${i}: text="${s}", role="${o}", label="${l}"`),{traceActualText:s,traceActualRole:o,traceActualAriaLabel:l,traceSelector:n.selector,traceStrategies:n.strategies}):null}_extractTextFromSelector(e){if(!e)return null;let r=e.match(/internal:label="([^"]+)"/);if(r)return r[1];let t=e.match(/internal:text="([^"]+)"/);if(t)return t[1];let i=e.match(/getByText\(['"]([^'"]+)['"]\)/);if(i)return i[1];let n=e.match(/name:\s*['"]([^'"]+)['"]/);return n?n[1]:null}};function Pe(h={}){let e=new S(h);return h.enableMCPRef!==!1&&e.register(new L(h)),h.enableTraceText!==!1&&e.register(new O(h)),h.enableAccessibility!==!1&&e.register(new P(h)),h.enablePageState!==!1&&e.register(new M(h)),h.enablePosition!==!1&&e.register(new R(h)),h.enableDOM!==!1&&e.register(new k(h)),e}function Me(h={}){let e=new S(h);return e.register(new P(h)),e.register(new M(h)),e}function Ae(h,e={}){let r=new S(e);for(let t of h)r.register(t);return r}export{P as AccessibilityEnricher,k as DOMEnricher,S as EnrichmentPipeline,g as EventEnricher,L as MCPRefEnricher,M as PageStateEnricher,R as PositionEnricher,O as TraceTextEnricher,Ae as createCustomPipeline,Pe as createDefaultPipeline,Me as createMinimalPipeline};
@@ -1 +1,4 @@
1
- import{createDefaultPipeline as l,createMinimalPipeline as p}from"./index.js";import{readFileSync as u,writeFileSync as s}from"fs";import{join as o}from"path";async function m(r,e={}){const n=o(r,"events.json"),c=o(r,"trace.zip");try{const t=JSON.parse(u(n,"utf-8")),i=t.map(h=>({...h,_enrichmentNote:"Full enrichment requires live Playwright access. Use EnrichmentPipeline during test execution."})),a=`${n}.backup`;return s(a,JSON.stringify(t,null,2)),s(n,JSON.stringify(i,null,2)),{enrichedCount:i.length,skippedCount:0,errors:[]}}catch(t){return console.error("[EnrichmentIntegration] Failed to enrich events:",t.message),{enrichedCount:0,skippedCount:0,errors:[t.message]}}}class v{constructor(e={}){this.pipeline=e.minimal?p(e):l(e),this.events=[],this.config=e}async recordEvent(e,n,c){const t={id:this.events.length,type:e,timestamp:new Date().toISOString(),data:n},i=await this.pipeline.enrich(t,{...c,event:t});return this.events.push(i),i}saveEvents(e){s(e,JSON.stringify(this.events,null,2)),console.log(`[LiveEnrichment] Saved ${this.events.length} enriched events to ${e}`),this.pipeline.logStatus()}getStats(){return this.pipeline.getStats()}}var y={enrichRecordedEvents:m,LiveEnrichmentRecorder:v};export{v as LiveEnrichmentRecorder,y as default,m as enrichRecordedEvents};
1
+ var g=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,n){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,n){return console.warn(`[${this.getName()}] Enrichment failed for event ${n.type}:`,e.message),null}};var T=class{constructor(e={}){this.enrichers=[],this.config=e,this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}register(e){return this.enrichers.push(e),this.enrichers.sort((n,t)=>t.getPriority()-n.getPriority()),this}unregister(e){return this.enrichers=this.enrichers.filter(n=>n.getName()!==e),this}get(e){return this.enrichers.find(n=>n.getName()===e)}setEnabled(e,n){let t=this.get(e);return t&&(t.enabled=n),this}async enrich(e,n){this.stats.totalEvents++;let t={...e},i=[],r=[],s=[];for(let o of this.enrichers)try{if(!o.canEnrich(n)){r.push(o.getName());continue}let c=Date.now(),a=await o.enrich(e,n),f=Date.now()-c;a?(Object.assign(t,a),i.push({name:o.getName(),duration:f})):r.push(o.getName())}catch(c){console.warn(`[EnrichmentPipeline] ${o.getName()} failed:`,c.message),s.push(o.getName()),this.stats.errors[o.getName()]=(this.stats.errors[o.getName()]||0)+1}return t._enrichment={version:"1.0",timestamp:new Date().toISOString(),enrichers:{run:i,skipped:r,failed:s}},i.length>0?this.stats.enrichedEvents++:this.stats.skippedEvents++,t}async enrichBatch(e,n){let t=[];for(let i of e){let r=await this.enrich(i,n);t.push(r)}return t}getStats(){return{...this.stats,enrichers:this.enrichers.map(e=>({name:e.getName(),enabled:e.enabled,priority:e.getPriority(),errors:this.stats.errors[e.getName()]||0}))}}resetStats(){this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}logStatus(){console.log(`
2
+ \u{1F4CA} Enrichment Pipeline Status:`),console.log(` Total events: ${this.stats.totalEvents}`),console.log(` Enriched: ${this.stats.enrichedEvents}`),console.log(` Skipped: ${this.stats.skippedEvents}`),console.log(`
3
+ Registered enrichers (${this.enrichers.length}):`);for(let e of this.enrichers){let n=e.enabled?"\u2713":"\u2717",t=this.stats.errors[e.getName()]||0,i=t>0?` (${t} errors)`:"";console.log(` ${n} ${e.getName()} (priority: ${e.getPriority()})${i}`)}console.log()}};var k=class extends g{getName(){return"PositionEnricher"}getPriority(){return 90}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,n){try{let{page:t,element:i}=n,r=await i.boundingBox();if(!r)return null;let s=await t.evaluate(()=>({scrollX:window.scrollX,scrollY:window.scrollY,width:window.innerWidth,height:window.innerHeight})),o=r.y>=s.scrollY&&r.y+r.height<=s.scrollY+s.height&&r.x>=0&&r.x+r.width<=s.width;return{position:{boundingBox:r,viewport:s,inViewport:o,centerPoint:{x:Math.round(r.x+r.width/2),y:Math.round(r.y+r.height/2)}}}}catch(t){return this.handleError(t,e)}}};import J from"crypto";var P=class extends g{getName(){return"AccessibilityEnricher"}getPriority(){return 100}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,n){try{let{page:t,element:i}=n,r=await t.accessibility.snapshot(),s=await this.findAxNode(i,r);if(!s)return null;let o=await this.getAxContext(s,r),c=this.hashAxSubtree(s),a=this.hashAxPath(o.path);return{accessibility:{role:s.role,name:s.name||"",level:o.level,parent:o.parent,siblings:o.siblings,axTreeHash:c,axPathHash:a}}}catch(t){return this.handleError(t,e)}}async findAxNode(e,n){let t=await e.evaluate(i=>({role:i.getAttribute("role")||i.tagName.toLowerCase(),name:i.getAttribute("aria-label")||i.textContent?.trim()||"",tagName:i.tagName.toLowerCase()}));return this.searchAxTree(n,t)}searchAxTree(e,n){if(!e)return null;if(e.role===n.role&&(e.name||"").includes(n.name.substring(0,20)))return e;if(e.children)for(let t of e.children){let i=this.searchAxTree(t,n);if(i)return i}return null}getAxContext(e,n){let t={level:0,parent:null,siblings:[],path:[]},i=this.findParent(e,n);return i&&(t.parent={role:i.role,name:i.name},t.siblings=(i.children||[]).filter(r=>r!==e).map(r=>({role:r.role,name:r.name})).slice(0,3)),t.level=this.calculateLevel(e,n),t.path=this.buildPath(e,n),t}findParent(e,n,t=n){if(!t||!t.children)return null;if(t.children.includes(e))return t;for(let i of t.children){let r=this.findParent(e,n,i);if(r)return r}return null}calculateLevel(e,n,t=n,i=0){if(t===e)return i;if(t.children)for(let r of t.children){let s=this.calculateLevel(e,n,r,i+1);if(s>=0)return s}return-1}buildPath(e,n,t=n,i=[]){if(t===e)return[...i,{role:t.role,name:t.name}];if(t.children)for(let r of t.children){let s=this.buildPath(e,n,r,[...i,{role:t.role,name:t.name}]);if(s)return s}return null}hashAxSubtree(e){let n=JSON.stringify({role:e.role,name:e.name,children:(e.children||[]).map(t=>({role:t.role,name:t.name}))});return J.createHash("md5").update(n).digest("hex").substring(0,12)}hashAxPath(e){let n=e.map(t=>`${t.role}:${t.name}`).join("/");return J.createHash("md5").update(n).digest("hex").substring(0,12)}};var M=class extends g{constructor(e={}){super(e),this.pendingRequests=new Set,this.setupNetworkTracking=!1}getName(){return"PageStateEnricher"}getPriority(){return 95}canEnrich(e){return this.enabled&&e.page}async setupTracking(e){this.setupNetworkTracking||(e.on("request",n=>{["document","xhr","fetch"].includes(n.resourceType())&&this.pendingRequests.add(n.url())}),e.on("requestfinished",n=>{this.pendingRequests.delete(n.url())}),e.on("requestfailed",n=>{this.pendingRequests.delete(n.url())}),this.setupNetworkTracking=!0)}async enrich(e,n){try{let{page:t}=n;await this.setupTracking(t);let i=await t.evaluate(()=>({readyState:document.readyState,domContentLoaded:document.readyState!=="loading",loadComplete:document.readyState==="complete",url:document.location.href})),r=await this.checkDOMStability(t);return{page:{networkIdle:this.pendingRequests.size===0,pendingRequests:this.pendingRequests.size,domStable:r,...i}}}catch(t){return this.handleError(t,e)}}async checkDOMStability(e,n=500){try{return await e.evaluate(i=>new Promise(r=>{let s,o=0,c=new MutationObserver(()=>{o++,clearTimeout(s),s=setTimeout(()=>{c.disconnect(),r(o===0)},i)});c.observe(document.body,{childList:!0,subtree:!0,attributes:!0}),s=setTimeout(()=>{c.disconnect(),r(!0)},i)}),n)}catch{return!1}}reset(){this.pendingRequests.clear(),this.setupNetworkTracking=!1}};var R=class extends g{getName(){return"DOMEnricher"}getPriority(){return 85}canEnrich(e){return!this.enabled||!e.element||!e.event?!1:["click","fill","type","selectOption","hover"].includes(e.event.type)}async enrich(e,n){try{let{element:t}=n,i=await t.evaluate(r=>{let s=l=>{let d=[],u=l;for(;u&&u!==document.body;){let x=u.tagName.toLowerCase(),b=u.parentElement;if(b){let y=Array.from(b.children).filter(N=>N.tagName===u.tagName);if(y.length>1){let N=y.indexOf(u)+1;x+=`:nth-child(${N})`}}d.unshift(x),u=u.parentElement}return`body > ${d.join(" > ")}`},o=l=>{let d=[],u=l;for(;u&&u!==document.body;){let x=1,b=u.previousSibling;for(;b;)b.nodeType===1&&b.tagName===u.tagName&&x++,b=b.previousSibling;let y=u.tagName.toLowerCase();d.unshift(`${y}[${x}]`),u=u.parentElement}return`/html/body/${d.join("/")}`},c={};for(let l of r.attributes)c[l.name]=l.value;let a=window.getComputedStyle(r),f={display:a.display,visibility:a.visibility,opacity:a.opacity,pointerEvents:a.pointerEvents},m=0,w=r.parentElement;for(;w;)m++,w=w.parentElement;return{path:s(r),xpath:o(r),depth:m,parent:r.parentElement?r.parentElement.tagName.toLowerCase():null,tagName:r.tagName.toLowerCase(),attributes:c,state:{visible:a.display!=="none"&&a.visibility!=="hidden",enabled:!r.disabled,focused:document.activeElement===r,...f}}});return{dom:{path:i.path,xpath:i.xpath,depth:i.depth,parent:i.parent,selector:this.buildSmartSelector(i)},attributes:i.attributes,state:i.state}}catch(t){return this.handleError(t,e)}}buildSmartSelector(e){let n=e.tagName;if(e.attributes.id)return`#${e.attributes.id}`;if(e.attributes["data-test-id"])return`[data-test-id="${e.attributes["data-test-id"]}"]`;if(e.attributes.class){let t=e.attributes.class.split(" ").filter(i=>i&&!i.match(/^(active|focus|hover|disabled)/));t.length>0&&(n+=`.${t.slice(0,2).join(".")}`)}return e.parent&&(n=`${e.parent} > ${n}`),n}};var O=class extends g{constructor(e={}){super(e),this.priority=200}getName(){return"MCPRef"}getPriority(){return this.priority}async enrich(e,n){let t=e.data?.params?.ref,i=e.data?.params?.element;if(!t&&!i)return null;let r=null,s=null,o=null;if(n?.element)try{let c=await n.element.evaluate(a=>({text:a.textContent?.trim()||"",innerText:a.innerText?.trim()||"",value:a.value||"",label:a.getAttribute("aria-label")||a.getAttribute("label")||"",role:a.getAttribute("role")||a.tagName.toLowerCase(),placeholder:a.getAttribute("placeholder")||"",title:a.getAttribute("title")||""}));r=c.text||c.innerText||c.value||c.placeholder,s=c.role,o=c.label||c.title,console.log(`[MCPRefEnricher] \u2705 Captured actual text: "${r}" (AI said: "${i}")`)}catch(c){console.log(`[MCPRefEnricher] \u26A0\uFE0F Could not extract actual text: ${c.message}`)}return{mcpRef:t,mcpElement:i,actualText:r,actualRole:s,actualLabel:o,recordedSelector:r||i}}};import{readFileSync as G,existsSync as H,readdirSync as W}from"fs";import{join as j}from"path";import{execSync as Q}from"child_process";import{tmpdir as ee}from"os";var z=class{static async parseTraceZip(e){let n;if(e.endsWith(".zip")&&H(e)){let t=j(ee(),`trace-${Date.now()}`);Q(`unzip -q "${e}" -d "${t}"`,{stdio:"pipe"});let r=W(t).find(s=>s.endsWith(".trace"));if(!r)throw new Error("No .trace file found in zip");n=j(t,r)}else if(H(e)){let i=W(e).find(r=>r.endsWith(".trace"));if(!i)throw new Error("No .trace file found");n=j(e,i)}else throw new Error(`Trace not found at ${e}`);try{let i=G(n,"utf-8").trim().split(`
4
+ `),r=[],s=new Map,o=new Map;for(let c of i)try{let a=JSON.parse(c);if(a.type==="snapshot"&&a.snapshot&&a.snapshot.accessibility){let f=new Map;for(let m of a.snapshot.accessibility)m.ref&&f.set(m.ref,m);s.set(a.snapshotName,f)}if(a.type==="frame-snapshot"&&a.snapshot){let f=Buffer.from(a.snapshot.html||"","base64").toString("utf-8");f&&f.length>100&&o.set(a.pageId||"default",f)}}catch{}for(let c of i)try{let a=JSON.parse(c);if(a.type==="before"&&a.params&&a.params.selector){let f=a.method;if(["click","fill","type","selectOption"].includes(f)){let m=a.params.selector,w=a.params.text||a.params.value||"",l=[],d=null,u=null,x=null,b=m.match(/aria-ref=([a-z0-9]+)/i);if(b&&a.snapshotName){let p=b[1],v=s.get(a.snapshotName);if(v&&v.has(p)){let E=v.get(p);d=E.name||null,u=E.role||null,x=E.label||null,console.log(`[TraceParser] \u2705 Found ACTUAL element data: text="${d}", role="${u}"`)}}let y=m.match(/internal:text="([^"]+)"/i),N=m.match(/internal:label="([^"]+)"/i),_=m.match(/internal:placeholder="([^"]+)"/i),B=m.match(/internal:role=([^ ]+)/i),A=m.match(/internal:describe="([^"]+)"/i),I=m.match(/name="([^"]+)"/i);if(y){l.push({type:"text",text:y[1]});let p=y[1].split(" ");p.length>1&&(l.push({type:"text",text:p[0],fuzzy:!0}),l.push({type:"text",text:p[p.length-1],fuzzy:!0}))}if(N&&l.push({type:"label",label:N[1]}),_&&l.push({type:"placeholder",placeholder:_[1]}),d){l.unshift({type:"text",text:d,source:"accessibility-tree"});let p=d.split(" ");p.length>1&&l.push({type:"text",text:p[0],fuzzy:!0,source:"accessibility-tree"})}if(u||B){let p=u||B[1],v=d||(I?I[1]:y?y[1]:null);l.unshift({type:"role",role:p,name:v,source:d?"accessibility-tree":"selector"})}if(x&&l.unshift({type:"label",label:x,source:"accessibility-tree"}),A){let p=A[1],v=["link","button","textbox","menuitem","submenu","combobox","checkbox","radio","tab","treeitem","menu item"],E=null,C=p;for(let S of v)if(p.toLowerCase().endsWith(` ${S}`)){E=S.replace(" ",""),C=p.substring(0,p.length-S.length-1);break}if(E){l.push({type:"role",role:E,name:C});let S=C.replace(/\s*\([^)]+\)\s*$/,"");l.push({type:"text",text:S}),l.push({type:"text",text:C});let F=C.split(" ");F.length>1&&(l.push({type:"text",text:F[0],fuzzy:!0}),l.push({type:"text",text:F.slice(0,2).join(" "),fuzzy:!0}))}else{let S=p.replace(/\s*\([^)]+\)\s*$/,"");l.push({type:"text",text:S}),l.push({type:"text",text:p})}}let K=this.extractDOMStrategies(m,o,y?.[1]||A?.[1],a.pageId);l.push(...K);let $=this.extractStructuralContext(m);($.parent||$.sibling)&&l.forEach(p=>{["role","text","label","testid"].includes(p.type)&&($.parent&&(p.parent=$.parent),$.sibling&&(p.sibling=$.sibling))}),l.push({type:"css",value:m});let V=d||y?y[1]:A?A[1].replace(/\s*\([^)]+\)\s*$/,""):`Action ${r.length}`;r.push({method:f,name:V,action:f==="type"?"fill":f,value:w,strategies:l,timestamp:a.startTime,actualText:d,actualRole:u,actualAriaLabel:x})}}}catch{}return r}catch(t){throw new Error(`Failed to parse trace: ${t.message}`,{cause:t})}}static extractDOMStrategies(e,n,t,i){let r=[];if(!n||n.size===0||!t)return r;try{let s=n.get(i);if(!s)return r;let o=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`data-testid=["']([^"']+)["'][^>]*>[^<]*${o}`,"i"),a=s.match(c);a&&r.push({type:"testid",value:a[1],priority:"high"});let f=new RegExp(`class=["']([^"']+)["'][^>]*>[^<]*${o}`,"gi"),m=s.matchAll(f);for(let d of m){let u=d[1].split(/\s+/).filter(x=>x&&!x.match(/^(css|jss|makeStyles|MuiBox|MuiStack)-\w+/)&&x.length>2);u.length>0&&(r.push({type:"class",value:u.join("."),priority:"medium"}),u.length===1&&r.push({type:"class",value:u[0],priority:"medium"}))}let w=new RegExp(`id=["']([^"']+)["'][^>]*>[^<]*${o}`,"i"),l=s.match(w);l&&!l[1].match(/^(root|app|\d+|[a-f0-9-]{20,})$/i)&&r.push({type:"id",value:l[1],priority:"high"})}catch(s){console.warn(`[TraceParser] DOM extraction failed: ${s.message}`)}return r}static extractStructuralContext(e){let n={parent:null,sibling:null},t=e.split(">>").map(s=>s.trim());if(t.length>1){let o=t[t.length-2].replace(/internal:text="[^"]+"\s*/gi,"").replace(/internal:role=\S+\s*/gi,"").replace(/internal:label="[^"]+"\s*/gi,"").trim();o&&(o.match(/^(form|section|nav|header|aside|main|article)\b/)||o.includes("[")||o.match(/[#.]\w/))&&(n.parent=o)}let r=t[t.length-1].match(/([^+~]+)\s*[+~]\s*(.+)/);return r&&(n.sibling=r[1].trim()),n}};import{existsSync as te}from"fs";import{join as Y}from"path";var L=class extends g{constructor(e={}){super(e),this.priority=190,this.traceData=null}getName(){return"TraceText"}getPriority(){return this.priority}async loadTrace(e){if(this.traceData)return;let n=Y(e,"traces"),t=Y(e,"trace.zip");if(te(t))try{this.traceData=await z.parseTraceZip(t),console.log(`[TraceTextEnricher] \u2705 Loaded trace with ${this.traceData.length} actions`)}catch(i){console.log(`[TraceTextEnricher] \u26A0\uFE0F Failed to parse trace: ${i.message}`)}}async enrich(e,n){let t=e.data?.params?.ref,i=e.id;if(t===void 0&&i===void 0||(!this.traceData&&n.sessionPath&&await this.loadTrace(n.sessionPath),!this.traceData))return null;let r=this.traceData[i];if(!r)return console.log(`[TraceTextEnricher] \u26A0\uFE0F No trace action for event ${i}`),null;let s=r.actualText||this._extractTextFromSelector(r.selector),o=r.actualRole,c=r.actualAriaLabel;return s||o||c?(console.log(`[TraceTextEnricher] \u2705 Event ${i}: text="${s}", role="${o}", label="${c}"`),{traceActualText:s,traceActualRole:o,traceActualAriaLabel:c,traceSelector:r.selector,traceStrategies:r.strategies}):null}_extractTextFromSelector(e){if(!e)return null;let n=e.match(/internal:label="([^"]+)"/);if(n)return n[1];let t=e.match(/internal:text="([^"]+)"/);if(t)return t[1];let i=e.match(/getByText\(['"]([^'"]+)['"]\)/);if(i)return i[1];let r=e.match(/name:\s*['"]([^'"]+)['"]/);return r?r[1]:null}};function X(h={}){let e=new T(h);return h.enableMCPRef!==!1&&e.register(new O(h)),h.enableTraceText!==!1&&e.register(new L(h)),h.enableAccessibility!==!1&&e.register(new P(h)),h.enablePageState!==!1&&e.register(new M(h)),h.enablePosition!==!1&&e.register(new k(h)),h.enableDOM!==!1&&e.register(new R(h)),e}function Z(h={}){let e=new T(h);return e.register(new P(h)),e.register(new M(h)),e}import{readFileSync as re,writeFileSync as q}from"fs";import{join as U}from"path";async function ne(h,e={}){let n=U(h,"events.json"),t=U(h,"trace.zip");try{let i=JSON.parse(re(n,"utf-8")),r=i.map(o=>({...o,_enrichmentNote:"Full enrichment requires live Playwright access. Use EnrichmentPipeline during test execution."})),s=`${n}.backup`;return q(s,JSON.stringify(i,null,2)),q(n,JSON.stringify(r,null,2)),{enrichedCount:r.length,skippedCount:0,errors:[]}}catch(i){return console.error("[EnrichmentIntegration] Failed to enrich events:",i.message),{enrichedCount:0,skippedCount:0,errors:[i.message]}}}var D=class{constructor(e={}){this.pipeline=e.minimal?Z(e):X(e),this.events=[],this.config=e}async recordEvent(e,n,t){let i={id:this.events.length,type:e,timestamp:new Date().toISOString(),data:n},r=await this.pipeline.enrich(i,{...t,event:i});return this.events.push(r),r}saveEvents(e){q(e,JSON.stringify(this.events,null,2)),console.log(`[LiveEnrichment] Saved ${this.events.length} enriched events to ${e}`),this.pipeline.logStatus()}getStats(){return this.pipeline.getStats()}},Ye={enrichRecordedEvents:ne,LiveEnrichmentRecorder:D};export{D as LiveEnrichmentRecorder,Ye as default,ne as enrichRecordedEvents};
@@ -1 +1 @@
1
- import{EventEnricher as u}from"./base.js";class p extends u{constructor(r={}){super(r),this.priority=200}getName(){return"MCPRef"}getPriority(){return this.priority}async enrich(r,n){const i=r.data?.params?.ref,a=r.data?.params?.element;if(!i&&!a)return null;let l=null,o=null,c=null;if(n?.element)try{const e=await n.element.evaluate(t=>({text:t.textContent?.trim()||"",innerText:t.innerText?.trim()||"",value:t.value||"",label:t.getAttribute("aria-label")||t.getAttribute("label")||"",role:t.getAttribute("role")||t.tagName.toLowerCase(),placeholder:t.getAttribute("placeholder")||"",title:t.getAttribute("title")||""}));l=e.text||e.innerText||e.value||e.placeholder,o=e.role,c=e.label||e.title,console.log(`[MCPRefEnricher] \u2705 Captured actual text: "${l}" (AI said: "${a}")`)}catch(e){console.log(`[MCPRefEnricher] \u26A0\uFE0F Could not extract actual text: ${e.message}`)}return{mcpRef:i,mcpElement:a,actualText:l,actualRole:o,actualLabel:c,recordedSelector:l||a}}}export{p as MCPRefEnricher};
1
+ var i=class{constructor(e={}){this.config=e,this.enabled=e.enabled!==!1,this.priority=e.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(e){return this.enabled}async enrich(e,a){throw new Error("EventEnricher.enrich() must be implemented")}handleError(e,a){return console.warn(`[${this.getName()}] Enrichment failed for event ${a.type}:`,e.message),null}};var u=class extends i{constructor(e={}){super(e),this.priority=200}getName(){return"MCPRef"}getPriority(){return this.priority}async enrich(e,a){let o=e.data?.params?.ref,l=e.data?.params?.element;if(!o&&!l)return null;let n=null,c=null,s=null;if(a?.element)try{let t=await a.element.evaluate(r=>({text:r.textContent?.trim()||"",innerText:r.innerText?.trim()||"",value:r.value||"",label:r.getAttribute("aria-label")||r.getAttribute("label")||"",role:r.getAttribute("role")||r.tagName.toLowerCase(),placeholder:r.getAttribute("placeholder")||"",title:r.getAttribute("title")||""}));n=t.text||t.innerText||t.value||t.placeholder,c=t.role,s=t.label||t.title,console.log(`[MCPRefEnricher] \u2705 Captured actual text: "${n}" (AI said: "${l}")`)}catch(t){console.log(`[MCPRefEnricher] \u26A0\uFE0F Could not extract actual text: ${t.message}`)}return{mcpRef:o,mcpElement:l,actualText:n,actualRole:c,actualLabel:s,recordedSelector:n||l}}};export{u as MCPRefEnricher};
@@ -1,3 +1,3 @@
1
- class l{constructor(e={}){this.enrichers=[],this.config=e,this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}register(e){return this.enrichers.push(e),this.enrichers.sort((t,s)=>s.getPriority()-t.getPriority()),this}unregister(e){return this.enrichers=this.enrichers.filter(t=>t.getName()!==e),this}get(e){return this.enrichers.find(t=>t.getName()===e)}setEnabled(e,t){const s=this.get(e);return s&&(s.enabled=t),this}async enrich(e,t){this.stats.totalEvents++;const s={...e},n=[],i=[],h=[];for(const r of this.enrichers)try{if(!r.canEnrich(t)){i.push(r.getName());continue}const o=Date.now(),c=await r.enrich(e,t),a=Date.now()-o;c?(Object.assign(s,c),n.push({name:r.getName(),duration:a})):i.push(r.getName())}catch(o){console.warn(`[EnrichmentPipeline] ${r.getName()} failed:`,o.message),h.push(r.getName()),this.stats.errors[r.getName()]=(this.stats.errors[r.getName()]||0)+1}return s._enrichment={version:"1.0",timestamp:new Date().toISOString(),enrichers:{run:n,skipped:i,failed:h}},n.length>0?this.stats.enrichedEvents++:this.stats.skippedEvents++,s}async enrichBatch(e,t){const s=[];for(const n of e){const i=await this.enrich(n,t);s.push(i)}return s}getStats(){return{...this.stats,enrichers:this.enrichers.map(e=>({name:e.getName(),enabled:e.enabled,priority:e.getPriority(),errors:this.stats.errors[e.getName()]||0}))}}resetStats(){this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}logStatus(){console.log(`
1
+ var h=class{constructor(e={}){this.enrichers=[],this.config=e,this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}register(e){return this.enrichers.push(e),this.enrichers.sort((t,s)=>s.getPriority()-t.getPriority()),this}unregister(e){return this.enrichers=this.enrichers.filter(t=>t.getName()!==e),this}get(e){return this.enrichers.find(t=>t.getName()===e)}setEnabled(e,t){let s=this.get(e);return s&&(s.enabled=t),this}async enrich(e,t){this.stats.totalEvents++;let s={...e},n=[],i=[],a=[];for(let r of this.enrichers)try{if(!r.canEnrich(t)){i.push(r.getName());continue}let o=Date.now(),c=await r.enrich(e,t),l=Date.now()-o;c?(Object.assign(s,c),n.push({name:r.getName(),duration:l})):i.push(r.getName())}catch(o){console.warn(`[EnrichmentPipeline] ${r.getName()} failed:`,o.message),a.push(r.getName()),this.stats.errors[r.getName()]=(this.stats.errors[r.getName()]||0)+1}return s._enrichment={version:"1.0",timestamp:new Date().toISOString(),enrichers:{run:n,skipped:i,failed:a}},n.length>0?this.stats.enrichedEvents++:this.stats.skippedEvents++,s}async enrichBatch(e,t){let s=[];for(let n of e){let i=await this.enrich(n,t);s.push(i)}return s}getStats(){return{...this.stats,enrichers:this.enrichers.map(e=>({name:e.getName(),enabled:e.enabled,priority:e.getPriority(),errors:this.stats.errors[e.getName()]||0}))}}resetStats(){this.stats={totalEvents:0,enrichedEvents:0,skippedEvents:0,errors:{}}}logStatus(){console.log(`
2
2
  \u{1F4CA} Enrichment Pipeline Status:`),console.log(` Total events: ${this.stats.totalEvents}`),console.log(` Enriched: ${this.stats.enrichedEvents}`),console.log(` Skipped: ${this.stats.skippedEvents}`),console.log(`
3
- Registered enrichers (${this.enrichers.length}):`);for(const e of this.enrichers){const t=e.enabled?"\u2713":"\u2717",s=this.stats.errors[e.getName()]||0,n=s>0?` (${s} errors)`:"";console.log(` ${t} ${e.getName()} (priority: ${e.getPriority()})${n}`)}console.log()}}var p=l;export{l as EnrichmentPipeline,p as default};
3
+ Registered enrichers (${this.enrichers.length}):`);for(let e of this.enrichers){let t=e.enabled?"\u2713":"\u2717",s=this.stats.errors[e.getName()]||0,n=s>0?` (${s} errors)`:"";console.log(` ${t} ${e.getName()} (priority: ${e.getPriority()})${n}`)}console.log()}},d=h;export{h as EnrichmentPipeline,d as default};
@@ -1 +1,2 @@
1
- import{EventEnricher as s}from"./base.js";import{TraceParser as u}from"../utils/trace-parser.js";import{existsSync as h}from"fs";import{join as l}from"path";class d extends s{constructor(t={}){super(t),this.priority=190,this.traceData=null}getName(){return"TraceText"}getPriority(){return this.priority}async loadTrace(t){if(this.traceData)return;const c=l(t,"traces"),a=l(t,"trace.zip");if(h(a))try{this.traceData=await u.parseTraceZip(a),console.log(`[TraceTextEnricher] \u2705 Loaded trace with ${this.traceData.length} actions`)}catch(r){console.log(`[TraceTextEnricher] \u26A0\uFE0F Failed to parse trace: ${r.message}`)}}async enrich(t,c){const a=t.data?.params?.ref,r=t.id;if(a===void 0&&r===void 0||(!this.traceData&&c.sessionPath&&await this.loadTrace(c.sessionPath),!this.traceData))return null;const e=this.traceData[r];if(!e)return console.log(`[TraceTextEnricher] \u26A0\uFE0F No trace action for event ${r}`),null;const n=e.actualText||this._extractTextFromSelector(e.selector),i=e.actualRole,o=e.actualAriaLabel;return n||i||o?(console.log(`[TraceTextEnricher] \u2705 Event ${r}: text="${n}", role="${i}", label="${o}"`),{traceActualText:n,traceActualRole:i,traceActualAriaLabel:o,traceSelector:e.selector,traceStrategies:e.strategies}):null}_extractTextFromSelector(t){if(!t)return null;const c=t.match(/internal:label="([^"]+)"/);if(c)return c[1];const a=t.match(/internal:text="([^"]+)"/);if(a)return a[1];const r=t.match(/getByText\(['"]([^'"]+)['"]\)/);if(r)return r[1];const e=t.match(/name:\s*['"]([^'"]+)['"]/);return e?e[1]:null}}export{d as TraceTextEnricher};
1
+ var M=class{constructor(t={}){this.config=t,this.enabled=t.enabled!==!1,this.priority=t.priority||50}getName(){throw new Error("EventEnricher.getName() must be implemented")}canEnrich(t){return this.enabled}async enrich(t,c){throw new Error("EventEnricher.enrich() must be implemented")}handleError(t,c){return console.warn(`[${this.getName()}] Enrichment failed for event ${c.type}:`,t.message),null}};import{readFileSync as B,existsSync as k,readdirSync as D}from"fs";import{join as z}from"path";import{execSync as W}from"child_process";import{tmpdir as I}from"os";var E=class{static async parseTraceZip(t){let c;if(t.endsWith(".zip")&&k(t)){let a=z(I(),`trace-${Date.now()}`);W(`unzip -q "${t}" -d "${a}"`,{stdio:"pipe"});let e=D(a).find(o=>o.endsWith(".trace"));if(!e)throw new Error("No .trace file found in zip");c=z(a,e)}else if(k(t)){let i=D(t).find(e=>e.endsWith(".trace"));if(!i)throw new Error("No .trace file found");c=z(t,i)}else throw new Error(`Trace not found at ${t}`);try{let i=B(c,"utf-8").trim().split(`
2
+ `),e=[],o=new Map,l=new Map;for(let m of i)try{let r=JSON.parse(m);if(r.type==="snapshot"&&r.snapshot&&r.snapshot.accessibility){let h=new Map;for(let p of r.snapshot.accessibility)p.ref&&h.set(p.ref,p);o.set(r.snapshotName,h)}if(r.type==="frame-snapshot"&&r.snapshot){let h=Buffer.from(r.snapshot.html||"","base64").toString("utf-8");h&&h.length>100&&l.set(r.pageId||"default",h)}}catch{}for(let m of i)try{let r=JSON.parse(m);if(r.type==="before"&&r.params&&r.params.selector){let h=r.method;if(["click","fill","type","selectOption"].includes(h)){let p=r.params.selector,S=r.params.text||r.params.value||"",s=[],u=null,f=null,d=null,R=p.match(/aria-ref=([a-z0-9]+)/i);if(R&&r.snapshotName){let n=R[1],y=o.get(r.snapshotName);if(y&&y.has(n)){let g=y.get(n);u=g.name||null,f=g.role||null,d=g.label||null,console.log(`[TraceParser] \u2705 Found ACTUAL element data: text="${u}", role="${f}"`)}}let x=p.match(/internal:text="([^"]+)"/i),A=p.match(/internal:label="([^"]+)"/i),F=p.match(/internal:placeholder="([^"]+)"/i),C=p.match(/internal:role=([^ ]+)/i),$=p.match(/internal:describe="([^"]+)"/i),L=p.match(/name="([^"]+)"/i);if(x){s.push({type:"text",text:x[1]});let n=x[1].split(" ");n.length>1&&(s.push({type:"text",text:n[0],fuzzy:!0}),s.push({type:"text",text:n[n.length-1],fuzzy:!0}))}if(A&&s.push({type:"label",label:A[1]}),F&&s.push({type:"placeholder",placeholder:F[1]}),u){s.unshift({type:"text",text:u,source:"accessibility-tree"});let n=u.split(" ");n.length>1&&s.push({type:"text",text:n[0],fuzzy:!0,source:"accessibility-tree"})}if(f||C){let n=f||C[1],y=u||(L?L[1]:x?x[1]:null);s.unshift({type:"role",role:n,name:y,source:u?"accessibility-tree":"selector"})}if(d&&s.unshift({type:"label",label:d,source:"accessibility-tree"}),$){let n=$[1],y=["link","button","textbox","menuitem","submenu","combobox","checkbox","radio","tab","treeitem","menu item"],g=null,T=n;for(let b of y)if(n.toLowerCase().endsWith(` ${b}`)){g=b.replace(" ",""),T=n.substring(0,n.length-b.length-1);break}if(g){s.push({type:"role",role:g,name:T});let b=T.replace(/\s*\([^)]+\)\s*$/,"");s.push({type:"text",text:b}),s.push({type:"text",text:T});let v=T.split(" ");v.length>1&&(s.push({type:"text",text:v[0],fuzzy:!0}),s.push({type:"text",text:v.slice(0,2).join(" "),fuzzy:!0}))}else{let b=n.replace(/\s*\([^)]+\)\s*$/,"");s.push({type:"text",text:b}),s.push({type:"text",text:n})}}let _=this.extractDOMStrategies(p,l,x?.[1]||$?.[1],r.pageId);s.push(..._);let w=this.extractStructuralContext(p);(w.parent||w.sibling)&&s.forEach(n=>{["role","text","label","testid"].includes(n.type)&&(w.parent&&(n.parent=w.parent),w.sibling&&(n.sibling=w.sibling))}),s.push({type:"css",value:p});let j=u||x?x[1]:$?$[1].replace(/\s*\([^)]+\)\s*$/,""):`Action ${e.length}`;e.push({method:h,name:j,action:h==="type"?"fill":h,value:S,strategies:s,timestamp:r.startTime,actualText:u,actualRole:f,actualAriaLabel:d})}}}catch{}return e}catch(a){throw new Error(`Failed to parse trace: ${a.message}`,{cause:a})}}static extractDOMStrategies(t,c,a,i){let e=[];if(!c||c.size===0||!a)return e;try{let o=c.get(i);if(!o)return e;let l=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),m=new RegExp(`data-testid=["']([^"']+)["'][^>]*>[^<]*${l}`,"i"),r=o.match(m);r&&e.push({type:"testid",value:r[1],priority:"high"});let h=new RegExp(`class=["']([^"']+)["'][^>]*>[^<]*${l}`,"gi"),p=o.matchAll(h);for(let u of p){let f=u[1].split(/\s+/).filter(d=>d&&!d.match(/^(css|jss|makeStyles|MuiBox|MuiStack)-\w+/)&&d.length>2);f.length>0&&(e.push({type:"class",value:f.join("."),priority:"medium"}),f.length===1&&e.push({type:"class",value:f[0],priority:"medium"}))}let S=new RegExp(`id=["']([^"']+)["'][^>]*>[^<]*${l}`,"i"),s=o.match(S);s&&!s[1].match(/^(root|app|\d+|[a-f0-9-]{20,})$/i)&&e.push({type:"id",value:s[1],priority:"high"})}catch(o){console.warn(`[TraceParser] DOM extraction failed: ${o.message}`)}return e}static extractStructuralContext(t){let c={parent:null,sibling:null},a=t.split(">>").map(o=>o.trim());if(a.length>1){let l=a[a.length-2].replace(/internal:text="[^"]+"\s*/gi,"").replace(/internal:role=\S+\s*/gi,"").replace(/internal:label="[^"]+"\s*/gi,"").trim();l&&(l.match(/^(form|section|nav|header|aside|main|article)\b/)||l.includes("[")||l.match(/[#.]\w/))&&(c.parent=l)}let e=a[a.length-1].match(/([^+~]+)\s*[+~]\s*(.+)/);return e&&(c.sibling=e[1].trim()),c}};import{existsSync as Z}from"fs";import{join as O}from"path";var P=class extends M{constructor(t={}){super(t),this.priority=190,this.traceData=null}getName(){return"TraceText"}getPriority(){return this.priority}async loadTrace(t){if(this.traceData)return;let c=O(t,"traces"),a=O(t,"trace.zip");if(Z(a))try{this.traceData=await E.parseTraceZip(a),console.log(`[TraceTextEnricher] \u2705 Loaded trace with ${this.traceData.length} actions`)}catch(i){console.log(`[TraceTextEnricher] \u26A0\uFE0F Failed to parse trace: ${i.message}`)}}async enrich(t,c){let a=t.data?.params?.ref,i=t.id;if(a===void 0&&i===void 0||(!this.traceData&&c.sessionPath&&await this.loadTrace(c.sessionPath),!this.traceData))return null;let e=this.traceData[i];if(!e)return console.log(`[TraceTextEnricher] \u26A0\uFE0F No trace action for event ${i}`),null;let o=e.actualText||this._extractTextFromSelector(e.selector),l=e.actualRole,m=e.actualAriaLabel;return o||l||m?(console.log(`[TraceTextEnricher] \u2705 Event ${i}: text="${o}", role="${l}", label="${m}"`),{traceActualText:o,traceActualRole:l,traceActualAriaLabel:m,traceSelector:e.selector,traceStrategies:e.strategies}):null}_extractTextFromSelector(t){if(!t)return null;let c=t.match(/internal:label="([^"]+)"/);if(c)return c[1];let a=t.match(/internal:text="([^"]+)"/);if(a)return a[1];let i=t.match(/getByText\(['"]([^'"]+)['"]\)/);if(i)return i[1];let e=t.match(/name:\s*['"]([^'"]+)['"]/);return e?e[1]:null}};export{P as TraceTextEnricher};