@atlaskit/ads-mcp 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +63 -2
  3. package/dist/cjs/helpers/analytics.js +98 -0
  4. package/dist/cjs/index.js +142 -28
  5. package/dist/cjs/tools/analyze-a11y/index.js +38 -38
  6. package/dist/cjs/tools/get-a11y-guidelines/index.js +4 -4
  7. package/dist/cjs/tools/get-all-icons/index.js +1 -1
  8. package/dist/cjs/tools/get-all-tokens/index.js +1 -1
  9. package/dist/cjs/tools/get-components/components.js +2 -2
  10. package/dist/cjs/tools/get-components/index.js +1 -1
  11. package/dist/cjs/tools/plan/index.js +6 -6
  12. package/dist/cjs/tools/search-components/index.js +9 -9
  13. package/dist/cjs/tools/search-icons/index.js +9 -9
  14. package/dist/cjs/tools/search-tokens/index.js +5 -5
  15. package/dist/cjs/tools/suggest-a11y-fixes/index.js +4 -4
  16. package/dist/es2019/helpers/analytics.js +88 -0
  17. package/dist/es2019/index.js +118 -15
  18. package/dist/es2019/tools/get-components/components.js +2 -2
  19. package/dist/esm/helpers/analytics.js +90 -0
  20. package/dist/esm/index.js +143 -29
  21. package/dist/esm/tools/analyze-a11y/index.js +38 -38
  22. package/dist/esm/tools/get-a11y-guidelines/index.js +4 -4
  23. package/dist/esm/tools/get-all-icons/index.js +1 -1
  24. package/dist/esm/tools/get-all-tokens/index.js +1 -1
  25. package/dist/esm/tools/get-components/components.js +2 -2
  26. package/dist/esm/tools/get-components/index.js +1 -1
  27. package/dist/esm/tools/plan/index.js +6 -6
  28. package/dist/esm/tools/search-components/index.js +9 -9
  29. package/dist/esm/tools/search-icons/index.js +9 -9
  30. package/dist/esm/tools/search-tokens/index.js +5 -5
  31. package/dist/esm/tools/suggest-a11y-fixes/index.js +4 -4
  32. package/dist/types/helpers/analytics.d.ts +28 -0
  33. package/dist/types/tools/get-components/components.d.ts +1 -1
  34. package/dist/types-ts4.5/helpers/analytics.d.ts +28 -0
  35. package/dist/types-ts4.5/tools/get-components/components.d.ts +1 -1
  36. package/package.json +4 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/ads-mcp
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`307bb9ca6972b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/307bb9ca6972b) -
8
+ Add analytics tracking for tool requests and errors
9
+
10
+ ## 0.7.3
11
+
12
+ ### Patch Changes
13
+
14
+ - [`1e36a2d0fe31e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1e36a2d0fe31e) -
15
+ Tiny update to form component types
16
+
3
17
  ## 0.7.2
4
18
 
5
19
  ### Patch Changes
package/README.md CHANGED
@@ -111,12 +111,70 @@ Add an entry to your `mcp.json` (eg. `~/.cursor/mcp.json` or wherever your MCP c
111
111
  "mcpServers": {
112
112
  "ads": {
113
113
  "command": "npx",
114
- "args": ["-y", "@atlaskit/ads-mcp"]
114
+ "args": ["-y", "@atlaskit/ads-mcp"],
115
+ "env": {
116
+ "ADSMCP_AGENT": "cursor"
117
+ }
115
118
  }
116
119
  }
117
120
  }
118
121
  ```
119
122
 
123
+ ### Environment Variables
124
+
125
+ - `ADSMCP_AGENT` - Identifies the AI agent/platform using the MCP server. Supported values:
126
+ - `cursor` - Cursor editor
127
+ - `vscode` - Visual Studio Code
128
+ - `rovodev` - Rovo Development environment
129
+ - `codelassian` - Codelassian platform
130
+ - `unknown` - Default value when not specified
131
+
132
+ The `ADSMCP_AGENT` variable helps track which platforms are using the MCP server for analytics purposes.
133
+
134
+ - `ADSMCP_ANALYTICS_OPT_OUT` - Opt out of analytics collection. Set to `true` to disable:
135
+ ```json
136
+ {
137
+ "mcpServers": {
138
+ "ads": {
139
+ "command": "npx",
140
+ "args": ["-y", "@atlaskit/ads-mcp"],
141
+ "env": {
142
+ "ADSMCP_AGENT": "cursor",
143
+ "ADSMCP_ANALYTICS_OPT_OUT": true
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ ## Analytics
151
+
152
+ The MCP server includes built-in analytics to help improve the service. Analytics are sent to
153
+ Atlassian's internal analytics system and track:
154
+
155
+ ### What We Track
156
+
157
+ - **Tool Usage**: Which tools are being called (e.g., `ads_plan`, `ads_analyze_a11y`)
158
+ - **Tool Parameters**: Arguments passed to tools (search terms, component names, etc.)
159
+ - **Success/Failure**: Whether tool calls succeed or fail, including error messages
160
+ - **Environment Context**:
161
+ - `agent`: The platform using the MCP server (from `ADSMCP_AGENT` env var)
162
+ - `os`: Operating system name (darwin, win32, linux)
163
+ - `osVersion`: Operating system version (e.g., 24.6.0 for macOS)
164
+ - `version`: The version of `@atlaskit/ads-mcp` being used
165
+ - `staffId`: User identifier (from `STAFF_ID`, `USER`, `ATLAS_USER`, or username)
166
+ - `timestamp`: When the event occurred
167
+
168
+ ### Privacy & Error Handling
169
+
170
+ - Analytics are collected for internal Atlassian use only to improve the MCP server
171
+ - **You can opt out** by setting `ADSMCP_ANALYTICS_OPT_OUT=true` in your environment variables
172
+ - If the analytics client fails to initialize or send events, the MCP server continues to work
173
+ normally
174
+ - All analytics errors are caught and logged, ensuring they never interrupt your workflow
175
+ - Events are batched and flushed every 5 seconds for efficiency
176
+
177
+
120
178
  ## Development
121
179
 
122
180
  You may automatically be served the local version of `@atlaskit/ads-mcp` depending on where you're
@@ -130,7 +188,10 @@ running it from, but you should force it like so:
130
188
  "args": [
131
189
  "-y",
132
190
  "~/git/atlassian/atlassian-frontend-monorepo/platform/packages/design-system/ads-mcp"
133
- ]
191
+ ],
192
+ "env": {
193
+ "ADSMCP_AGENT": "cursor"
194
+ }
134
195
  }
135
196
  }
136
197
  }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.configPath = exports.agent = void 0;
8
+ exports.sendOperationalEvent = sendOperationalEvent;
9
+ exports.staffId = void 0;
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _nodeOs = require("node:os");
12
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
13
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable no-console */
14
+ // eslint-disable-next-line import/no-extraneous-dependencies -- this uses require because not all node versions this package supports use the same import assertions/attributes
15
+ var pkgJson = require('@atlaskit/ads-mcp/package.json');
16
+ var version = pkgJson.version || '0.0.0-unknown';
17
+
18
+ // Get staff ID using the same logic as @repo-feature-flags-statsig
19
+ var staffId = exports.staffId = process.env.STAFF_ID || process.env.USER || process.env.ATLAS_USER || (0, _nodeOs.userInfo)().username;
20
+
21
+ /**
22
+ * This is a user-passed value via environment to define what agent we may be running in.
23
+ * This could be anything, do not rely on it!
24
+ * @default `'unknown'`
25
+ */
26
+
27
+ var agent = exports.agent = process.env.ADSMCP_AGENT || 'unknown';
28
+
29
+ /**
30
+ * The path to the MCP config file that is being used to run the MCP server
31
+ * e.g. 'mcp.json', 'jira/.cursor/mcp.json', 'platform/.vscode/mcp.json' or 'unknown'
32
+ * This could be anything, do not rely on it!
33
+ * @default `'unknown'`
34
+ */
35
+ var configPath = exports.configPath = process.env.ADSMCP_CONFIG_PATH || 'unknown';
36
+
37
+ // Check if user has opted out of analytics
38
+ var isAnalyticsOptedOut = String(process.env.ADSMCP_ANALYTICS_OPT_OUT) === 'true' || String(process.env.ADSMCP_ANALYTICS_OPT_OUT) === '1';
39
+
40
+ // Initialize analytics client with error handling
41
+ // If analytics client fails to initialize or user has opted out, we continue without analytics
42
+ var analyticsClient = null;
43
+ if (!isAnalyticsOptedOut) {
44
+ try {
45
+ // Dynamic import to catch initialization errors
46
+ var _require = require('@atlassiansox/analytics-node-client'),
47
+ createAnalyticsClient = _require.analyticsClient;
48
+ analyticsClient = createAnalyticsClient({
49
+ env: process.env.NODE_ENV === 'development' ? 'dev' : 'prod',
50
+ product: 'atlaskit',
51
+ subproduct: 'ads-mcp',
52
+ flushInterval: 5000
53
+ });
54
+ } catch (error) {
55
+ // Analytics client not available or failed to initialize
56
+ // Log the error but continue without analytics
57
+ console.error('Could not initialize analytics client. This is normal as it is only intended to measure authenticated Atlassians');
58
+ }
59
+ }
60
+ /**
61
+ * Send an operational event to analytics
62
+ * Wraps the analytics client and handles errors gracefully
63
+ * If analytics client is not available, this function is a no-op
64
+ */
65
+ function sendOperationalEvent(_ref) {
66
+ var action = _ref.action,
67
+ actionSubject = _ref.actionSubject,
68
+ _ref$actionSubjectId = _ref.actionSubjectId,
69
+ actionSubjectId = _ref$actionSubjectId === void 0 ? '' : _ref$actionSubjectId,
70
+ _ref$attributes = _ref.attributes,
71
+ attributes = _ref$attributes === void 0 ? {} : _ref$attributes;
72
+ // If analytics client is not available, skip analytics
73
+ if (!analyticsClient) {
74
+ return;
75
+ }
76
+ try {
77
+ analyticsClient.sendOperationalEvent({
78
+ anonymousId: 'unknown',
79
+ operationalEvent: {
80
+ action: action,
81
+ actionSubject: actionSubject,
82
+ actionSubjectId: actionSubjectId,
83
+ source: '@atlaskit/ads-mcp',
84
+ tags: ['ads-mcp'],
85
+ attributes: _objectSpread({
86
+ version: version,
87
+ staffId: staffId,
88
+ agent: agent,
89
+ configPath: configPath
90
+ }, attributes)
91
+ }
92
+ });
93
+ } catch (error) {
94
+ // Analytics errors should not prevent normal operation
95
+ // Silently fail to avoid disrupting the main functionality
96
+ console.error('Error sending operational event to analytics');
97
+ }
98
+ }
package/dist/cjs/index.js CHANGED
@@ -6,6 +6,7 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
6
6
  var _index = require("@modelcontextprotocol/sdk/server/index.js");
7
7
  var _stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
8
8
  var _types = require("@modelcontextprotocol/sdk/types.js");
9
+ var _analytics = require("./helpers/analytics");
9
10
  var _instructions = require("./instructions");
10
11
  var _analyzeA11y = require("./tools/analyze-a11y");
11
12
  var _getA11yGuidelines = require("./tools/get-a11y-guidelines");
@@ -17,7 +18,7 @@ var _searchComponents = require("./tools/search-components");
17
18
  var _searchIcons = require("./tools/search-icons");
18
19
  var _searchTokens = require("./tools/search-tokens");
19
20
  var _suggestA11yFixes = require("./tools/suggest-a11y-fixes");
20
- /* eslint-disable import/extensions */
21
+ /* eslint-disable no-console, import/extensions */
21
22
 
22
23
  // eslint-disable-next-line import/no-extraneous-dependencies -- this uses require because not all node versions this package supports use the same import assertions/attributes
23
24
  var pkgJson = require('@atlaskit/ads-mcp/package.json');
@@ -27,29 +28,68 @@ var server = new _index.Server({
27
28
  }, {
28
29
  instructions: _instructions.instructions,
29
30
  capabilities: {
31
+ // logging: {}, // NOTE: We do not have logging enabled as it's not implemented consistently in MCP specs
30
32
  // Tools are defined in the handlers below.
31
33
  tools: {}
32
34
  }
33
35
  });
34
- server.setRequestHandler(_types.ListToolsRequestSchema, /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
35
- return _regenerator.default.wrap(function _callee$(_context) {
36
- while (1) switch (_context.prev = _context.next) {
37
- case 0:
38
- return _context.abrupt("return", {
39
- tools: [_analyzeA11y.listAnalyzeA11yTool, _analyzeA11y.listAnalyzeLocalhostA11yTool, _getA11yGuidelines.listGetA11yGuidelinesTool, _getAllIcons.listGetAllIconsTool, _getAllTokens.listGetAllTokensTool, _getComponents.listGetComponentsTool, _plan.listPlanTool,
36
+ var generateLogger = function generateLogger(level) {
37
+ return function () {
38
+ // NOTE: We do not have logging enabled as it's not implemented consistently in MCP specs
39
+ // server.sendLoggingMessage({
40
+ // level,
41
+ // data: args,
42
+ // });
43
+
44
+ // Log to console if ADSMCP_DEBUG is set to true
45
+ // using console.error since the only one that works for logging is `stderr`
46
+ // using console.log / other console.fn that use `stdout` will cause an error
47
+ // ref: https://www.mcpevals.io/blog/debugging-mcp-servers-tips-and-best-practices
48
+ if (String(process.env.ADSMCP_DEBUG) === 'true') {
49
+ var _console;
50
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
51
+ args[_key] = arguments[_key];
52
+ }
53
+ (_console = console).error.apply(_console, ["[ads-mcp.custom-logging][".concat(level, "]")].concat(args));
54
+ }
55
+ };
56
+ };
57
+ server.setRequestHandler(_types.ListToolsRequestSchema, /*#__PURE__*/function () {
58
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(request, extra) {
59
+ var tools;
60
+ return _regenerator.default.wrap(function (_context) {
61
+ while (1) switch (_context.prev = _context.next) {
62
+ case 0:
63
+ tools = [_analyzeA11y.listAnalyzeA11yTool, _analyzeA11y.listAnalyzeLocalhostA11yTool, _getA11yGuidelines.listGetA11yGuidelinesTool, _getAllIcons.listGetAllIconsTool, _getAllTokens.listGetAllTokensTool, _getComponents.listGetComponentsTool, _plan.listPlanTool,
40
64
  // NOTE: These are disabled as `ads_plan` should cover everything more performantly.
41
65
  // When these are enabled, they result in token usage to describe them, even if never used.
42
66
  // listSearchComponentsTool,
43
67
  // listSearchIconsTool,
44
68
  // listSearchTokensTool,
45
- _suggestA11yFixes.listSuggestA11yFixesTool]
46
- });
47
- case 1:
48
- case "end":
49
- return _context.stop();
50
- }
51
- }, _callee);
52
- })));
69
+ _suggestA11yFixes.listSuggestA11yFixesTool]; // Track list tools request
70
+ (0, _analytics.sendOperationalEvent)({
71
+ action: 'listed',
72
+ actionSubject: 'ads.mcp.listTools',
73
+ attributes: {
74
+ toolsCount: tools.length,
75
+ // Number of available tools
76
+ request: request,
77
+ extra: extra
78
+ }
79
+ });
80
+ return _context.abrupt("return", {
81
+ tools: tools
82
+ });
83
+ case 1:
84
+ case "end":
85
+ return _context.stop();
86
+ }
87
+ }, _callee);
88
+ }));
89
+ return function (_x, _x2) {
90
+ return _ref.apply(this, arguments);
91
+ };
92
+ }());
53
93
  var callTools = {
54
94
  ads_analyze_a11y: _analyzeA11y.analyzeA11yTool,
55
95
  ads_analyze_localhost_a11y: _analyzeA11y.analyzeLocalhostA11yTool,
@@ -68,26 +108,87 @@ var callTools = {
68
108
 
69
109
  // Handle tool execution
70
110
  server.setRequestHandler(_types.CallToolRequestSchema, /*#__PURE__*/function () {
71
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(request) {
72
- var tool;
73
- return _regenerator.default.wrap(function _callee2$(_context2) {
111
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(request, extra) {
112
+ var toolName, tool, actionSubject, result, _t;
113
+ return _regenerator.default.wrap(function (_context2) {
74
114
  while (1) switch (_context2.prev = _context2.next) {
75
115
  case 0:
76
- tool = callTools[request.params.name];
116
+ toolName = request.params.name;
117
+ tool = callTools[toolName];
118
+ actionSubject = "ads.mcp.callTool"; // Track call tool request
119
+ (0, _analytics.sendOperationalEvent)({
120
+ action: 'called',
121
+ actionSubject: actionSubject,
122
+ actionSubjectId: toolName,
123
+ attributes: {
124
+ toolName: toolName,
125
+ request: request,
126
+ extra: extra
127
+ }
128
+ });
77
129
  if (!tool) {
78
- _context2.next = 3;
130
+ _context2.next = 4;
79
131
  break;
80
132
  }
81
- return _context2.abrupt("return", tool(request.params.arguments));
133
+ _context2.prev = 1;
134
+ _context2.next = 2;
135
+ return tool(request.params.arguments);
136
+ case 2:
137
+ result = _context2.sent;
138
+ // Track successful tool execution
139
+ (0, _analytics.sendOperationalEvent)({
140
+ action: 'succeeded',
141
+ actionSubject: actionSubject,
142
+ actionSubjectId: toolName,
143
+ attributes: {
144
+ toolName: toolName,
145
+ request: request,
146
+ extra: extra
147
+ }
148
+ });
149
+ return _context2.abrupt("return", result);
82
150
  case 3:
83
- throw new Error("Tool '".concat(request.params.name, "' not found, only the following tools are available: ").concat(Object.keys(callTools).join(', ')));
151
+ _context2.prev = 3;
152
+ _t = _context2["catch"](1);
153
+ // Track tool execution error
154
+ (0, _analytics.sendOperationalEvent)({
155
+ action: 'failed',
156
+ actionSubject: actionSubject,
157
+ actionSubjectId: toolName,
158
+ attributes: {
159
+ toolName: toolName,
160
+ request: request,
161
+ extra: extra,
162
+ errorMessage: _t instanceof Error ? _t.message : 'Unknown error'
163
+ }
164
+ });
165
+
166
+ /* Throwing an MCP error will cause the MCP server to return an error response to the client.
167
+ We don't use console.error here:
168
+ - when used alone, without the throw new McpError, it causes "Client error for command...", which will loop back to this catch
169
+ */
170
+ throw new _types.McpError(-32000, "Failed to execute '".concat(toolName, "' tool: ").concat(_t instanceof Error ? _t.message : 'Unknown error'));
84
171
  case 4:
172
+ // Track tool not found error
173
+ (0, _analytics.sendOperationalEvent)({
174
+ action: 'notFound',
175
+ actionSubject: actionSubject,
176
+ actionSubjectId: toolName,
177
+ attributes: {
178
+ toolName: toolName,
179
+ request: request,
180
+ extra: extra
181
+ }
182
+ });
183
+ console.error("Tool '".concat(request.params.name, "' not found, only the following tools are available: ").concat(Object.keys(callTools).join(', ')));
184
+ return _context2.abrupt("return");
185
+ case 5:
85
186
  case "end":
86
187
  return _context2.stop();
87
188
  }
88
- }, _callee2);
189
+ }, _callee2, null, [[1, 3]]);
89
190
  }));
90
- return function (_x) {
191
+ return function (_x3, _x4) {
91
192
  return _ref2.apply(this, arguments);
92
193
  };
93
194
  }());
@@ -97,13 +198,25 @@ function runServer() {
97
198
  function _runServer() {
98
199
  _runServer = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
99
200
  var transport;
100
- return _regenerator.default.wrap(function _callee3$(_context3) {
201
+ return _regenerator.default.wrap(function (_context3) {
101
202
  while (1) switch (_context3.prev = _context3.next) {
102
203
  case 0:
204
+ /**
205
+ * We force all logging to go through the MCP server to avoid breaking the MCP.
206
+ */
207
+ console.log = generateLogger('info');
208
+ console.debug = generateLogger('debug');
209
+ console.warn = generateLogger('warning');
210
+
211
+ // Track server initialization
212
+ (0, _analytics.sendOperationalEvent)({
213
+ action: 'initialized',
214
+ actionSubject: 'ads.mcp.initialize'
215
+ });
103
216
  transport = new _stdio.StdioServerTransport();
104
- _context3.next = 3;
217
+ _context3.next = 1;
105
218
  return server.connect(transport);
106
- case 3:
219
+ case 1:
107
220
  case "end":
108
221
  return _context3.stop();
109
222
  }
@@ -112,5 +225,6 @@ function _runServer() {
112
225
  return _runServer.apply(this, arguments);
113
226
  }
114
227
  runServer().catch(function (error) {
115
- throw new Error("Invalid input to ads-mcp: ".concat(JSON.stringify(error.errors)));
228
+ var errorMessage = error instanceof Error ? error.message : 'Unknown error';
229
+ console.error("Invalid input to ads-mcp: ".concat(errorMessage));
116
230
  });
@@ -152,20 +152,20 @@ function generateADSFixForViolation(violation) {
152
152
  }
153
153
  var analyzeA11yTool = exports.analyzeA11yTool = /*#__PURE__*/function () {
154
154
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(params) {
155
- var code, componentName, context, _params$includePatter, includePatternAnalysis, violations, suggestions, axeResults, _axeResults$violation, _axeResults$passes, _axeResults$incomplet, results, adsViolations, relevantGuidelines, summary;
156
- return _regenerator.default.wrap(function _callee$(_context) {
155
+ var code, componentName, context, _params$includePatter, includePatternAnalysis, violations, suggestions, axeResults, _axeResults$violation, _axeResults$passes, _axeResults$incomplet, results, adsViolations, relevantGuidelines, summary, _t;
156
+ return _regenerator.default.wrap(function (_context) {
157
157
  while (1) switch (_context.prev = _context.next) {
158
158
  case 0:
159
159
  code = params.code, componentName = params.componentName, context = params.context, _params$includePatter = params.includePatternAnalysis, includePatternAnalysis = _params$includePatter === void 0 ? true : _params$includePatter;
160
160
  violations = [];
161
161
  suggestions = [];
162
162
  axeResults = {};
163
- _context.prev = 4;
164
- _context.next = 7;
163
+ _context.prev = 1;
164
+ _context.next = 2;
165
165
  return _axeCore.default.run({
166
166
  fromFrames: ['iframe', 'html']
167
167
  });
168
- case 7:
168
+ case 2:
169
169
  results = _context.sent;
170
170
  // Process axe-core results
171
171
  if (results.violations && results.violations.length > 0) {
@@ -251,9 +251,9 @@ var analyzeA11yTool = exports.analyzeA11yTool = /*#__PURE__*/function () {
251
251
  }, null, 2)
252
252
  }]
253
253
  });
254
- case 20:
255
- _context.prev = 20;
256
- _context.t0 = _context["catch"](4);
254
+ case 3:
255
+ _context.prev = 3;
256
+ _t = _context["catch"](1);
257
257
  // Fallback to pattern-based analysis if axe-core fails
258
258
  // console.warn('Axe-core analysis failed, falling back to pattern analysis:', error);
259
259
 
@@ -302,11 +302,11 @@ var analyzeA11yTool = exports.analyzeA11yTool = /*#__PURE__*/function () {
302
302
  }, null, 2)
303
303
  }]
304
304
  });
305
- case 24:
305
+ case 4:
306
306
  case "end":
307
307
  return _context.stop();
308
308
  }
309
- }, _callee, null, [[4, 20]]);
309
+ }, _callee, null, [[1, 3]]);
310
310
  }));
311
311
  return function analyzeA11yTool(_x) {
312
312
  return _ref.apply(this, arguments);
@@ -314,59 +314,59 @@ var analyzeA11yTool = exports.analyzeA11yTool = /*#__PURE__*/function () {
314
314
  }();
315
315
  var analyzeLocalhostA11yTool = exports.analyzeLocalhostA11yTool = /*#__PURE__*/function () {
316
316
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(params) {
317
- var url, componentName, context, selector, violations, suggestions, axeResults, browser, page, _axeResults$violation2, _axeResults$passes2, _axeResults$incomplet2, elementExists, availableElements, axePuppeteer, results, adsViolations, relevantGuidelines, summary;
318
- return _regenerator.default.wrap(function _callee2$(_context2) {
317
+ var url, componentName, context, selector, violations, suggestions, axeResults, browser, page, _axeResults$violation2, _axeResults$passes2, _axeResults$incomplet2, elementExists, availableElements, axePuppeteer, results, adsViolations, relevantGuidelines, summary, _t2;
318
+ return _regenerator.default.wrap(function (_context2) {
319
319
  while (1) switch (_context2.prev = _context2.next) {
320
320
  case 0:
321
321
  url = params.url, componentName = params.componentName, context = params.context, selector = params.selector;
322
322
  violations = [];
323
323
  suggestions = [];
324
324
  axeResults = {};
325
- _context2.next = 6;
325
+ _context2.next = 1;
326
326
  return _puppeteer2.default.launch();
327
- case 6:
327
+ case 1:
328
328
  browser = _context2.sent;
329
- _context2.next = 9;
329
+ _context2.next = 2;
330
330
  return browser.newPage();
331
- case 9:
331
+ case 2:
332
332
  page = _context2.sent;
333
- _context2.prev = 10;
334
- _context2.next = 13;
333
+ _context2.prev = 3;
334
+ _context2.next = 4;
335
335
  return page.goto(url, {
336
336
  waitUntil: 'networkidle0'
337
337
  });
338
- case 13:
338
+ case 4:
339
339
  if (!selector) {
340
- _context2.next = 22;
340
+ _context2.next = 7;
341
341
  break;
342
342
  }
343
- _context2.next = 16;
343
+ _context2.next = 5;
344
344
  return page.$(selector);
345
- case 16:
345
+ case 5:
346
346
  elementExists = _context2.sent;
347
347
  if (elementExists) {
348
- _context2.next = 22;
348
+ _context2.next = 7;
349
349
  break;
350
350
  }
351
- _context2.next = 20;
351
+ _context2.next = 6;
352
352
  return page.evaluate(function () {
353
353
  var elements = Array.from(document.querySelectorAll('[id]'));
354
354
  return elements.map(function (el) {
355
355
  return "#".concat(el.id);
356
356
  });
357
357
  });
358
- case 20:
358
+ case 6:
359
359
  availableElements = _context2.sent;
360
360
  throw new Error("Element with selector \"".concat(selector, "\" not found on the page after waiting. Available elements: ").concat(availableElements.join(', ')));
361
- case 22:
361
+ case 7:
362
362
  // Run axe-core accessibility analysis
363
363
  axePuppeteer = new _puppeteer.AxePuppeteer(page); // If selector is provided, analyze only that element
364
364
  if (selector) {
365
365
  axePuppeteer.include(selector);
366
366
  }
367
- _context2.next = 26;
367
+ _context2.next = 8;
368
368
  return axePuppeteer.analyze();
369
- case 26:
369
+ case 8:
370
370
  results = _context2.sent;
371
371
  if (results.violations && results.violations.length > 0) {
372
372
  adsViolations = mapAxeViolationsToADSFixes(results.violations);
@@ -422,9 +422,9 @@ var analyzeLocalhostA11yTool = exports.analyzeLocalhostA11yTool = /*#__PURE__*/f
422
422
  incomplete: ((_axeResults$incomplet2 = axeResults.incomplete) === null || _axeResults$incomplet2 === void 0 ? void 0 : _axeResults$incomplet2.length) || 0
423
423
  }
424
424
  };
425
- _context2.next = 37;
425
+ _context2.next = 9;
426
426
  return browser.close();
427
- case 37:
427
+ case 9:
428
428
  return _context2.abrupt("return", {
429
429
  content: [{
430
430
  type: 'text',
@@ -438,12 +438,12 @@ var analyzeLocalhostA11yTool = exports.analyzeLocalhostA11yTool = /*#__PURE__*/f
438
438
  }, null, 2)
439
439
  }]
440
440
  });
441
- case 40:
442
- _context2.prev = 40;
443
- _context2.t0 = _context2["catch"](10);
444
- _context2.next = 44;
441
+ case 10:
442
+ _context2.prev = 10;
443
+ _t2 = _context2["catch"](3);
444
+ _context2.next = 11;
445
445
  return browser.close();
446
- case 44:
446
+ case 11:
447
447
  return _context2.abrupt("return", {
448
448
  content: [{
449
449
  type: 'text',
@@ -466,16 +466,16 @@ var analyzeLocalhostA11yTool = exports.analyzeLocalhostA11yTool = /*#__PURE__*/f
466
466
  },
467
467
  violations: violations,
468
468
  suggestions: [],
469
- error: String(_context2.t0),
469
+ error: String(_t2),
470
470
  recommendations: ['Use ADS components for better accessibility out of the box', 'Reference https://atlassian.design/llms-a11y.txt for detailed guidelines', 'Test with keyboard navigation and screen readers', 'Use automated accessibility testing tools']
471
471
  }, null, 2)
472
472
  }]
473
473
  });
474
- case 45:
474
+ case 12:
475
475
  case "end":
476
476
  return _context2.stop();
477
477
  }
478
- }, _callee2, null, [[10, 40]]);
478
+ }, _callee2, null, [[3, 10]]);
479
479
  }));
480
480
  return function analyzeLocalhostA11yTool(_x2) {
481
481
  return _ref2.apply(this, arguments);
@@ -32,12 +32,12 @@ var listGetA11yGuidelinesTool = exports.listGetA11yGuidelinesTool = {
32
32
  var getA11yGuidelinesTool = exports.getA11yGuidelinesTool = /*#__PURE__*/function () {
33
33
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
34
34
  var topic, guidelines;
35
- return _regenerator.default.wrap(function _callee$(_context) {
35
+ return _regenerator.default.wrap(function (_context) {
36
36
  while (1) switch (_context.prev = _context.next) {
37
37
  case 0:
38
38
  topic = _ref.topic;
39
39
  if (!(topic && _guidelines.accessibilityGuidelines[topic])) {
40
- _context.next = 4;
40
+ _context.next = 1;
41
41
  break;
42
42
  }
43
43
  guidelines = _guidelines.accessibilityGuidelines[topic];
@@ -51,7 +51,7 @@ var getA11yGuidelinesTool = exports.getA11yGuidelinesTool = /*#__PURE__*/functio
51
51
  }), null, 2)
52
52
  }]
53
53
  });
54
- case 4:
54
+ case 1:
55
55
  return _context.abrupt("return", {
56
56
  content: [{
57
57
  type: 'text',
@@ -63,7 +63,7 @@ var getA11yGuidelinesTool = exports.getA11yGuidelinesTool = /*#__PURE__*/functio
63
63
  }, null, 2)
64
64
  }]
65
65
  });
66
- case 5:
66
+ case 2:
67
67
  case "end":
68
68
  return _context.stop();
69
69
  }
@@ -40,7 +40,7 @@ var listGetAllIconsTool = exports.listGetAllIconsTool = {
40
40
  };
41
41
  var getAllIconsTool = exports.getAllIconsTool = /*#__PURE__*/function () {
42
42
  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
43
- return _regenerator.default.wrap(function _callee$(_context) {
43
+ return _regenerator.default.wrap(function (_context) {
44
44
  while (1) switch (_context.prev = _context.next) {
45
45
  case 0:
46
46
  return _context.abrupt("return", {
@@ -25,7 +25,7 @@ var listGetAllTokensTool = exports.listGetAllTokensTool = {
25
25
  };
26
26
  var getAllTokensTool = exports.getAllTokensTool = /*#__PURE__*/function () {
27
27
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
28
- return _regenerator.default.wrap(function _callee$(_context) {
28
+ return _regenerator.default.wrap(function (_context) {
29
29
  while (1) switch (_context.prev = _context.next) {
30
30
  case 0:
31
31
  return _context.abrupt("return", {