@locofy/mcp 1.0.9 → 1.0.11

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.
@@ -0,0 +1,7 @@
1
+ const isDev = process.env.IS_DEV === 'true';
2
+ export const MIXPANEL_PROJECT_TOKEN = isDev
3
+ ? '77d8775b23ede44f6f58a6a0c677e881'
4
+ : '6ba4b43a52dcbc80ee759b59f2dc8c5f';
5
+ export const MIXPANEL_PROXY_DOMAIN = isDev
6
+ ? 'https://event-tracking.locofy.dev/events/mixpanel'
7
+ : 'https://events.locofy.ai/events/mixpanel';
@@ -3,6 +3,7 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import axios from 'axios';
5
5
  import { getProjectID } from '../helpers/helpers.js';
6
+ import { track } from '../utils/analytics.js';
6
7
  /**
7
8
  * PullComponents tool
8
9
  * - Returns a hardcoded representation of a directory structure
@@ -31,6 +32,7 @@ export async function runPullComponentsTool(args) {
31
32
  try {
32
33
  const result = await fetchDirectoryStructure(componentNames, projectID, personalAccessToken);
33
34
  if (result.success) {
35
+ const userID = result.user_id;
34
36
  // Prepend workspacePath to all filePath attributes
35
37
  prepareFilePaths(result.data, workspacePath);
36
38
  // Download and save any files referenced in the response
@@ -39,10 +41,12 @@ export async function runPullComponentsTool(args) {
39
41
  await checkForCodeChanges(result.data);
40
42
  // clean the directory structure
41
43
  const cleanedResult = processDirectoryStructure(result.data);
42
- // write resultJSON to a file
43
- if (process.env.DEBUG_MODE === 'true') {
44
- fs.writeFileSync('result.json', JSON.stringify(cleanedResult, null, 2));
45
- }
44
+ track('mcp_execute_tool_e', {
45
+ tool_name: pullComponentsToolName,
46
+ project_id: projectID,
47
+ user_id: userID,
48
+ source: 'cursor', // TODO: update it when we release vscode extension
49
+ });
46
50
  return {
47
51
  content: [
48
52
  {
@@ -111,7 +115,8 @@ async function fetchDirectoryStructure(componentNames, projectID, personalAccess
111
115
  }
112
116
  return {
113
117
  success: true,
114
- data: response.data.directoryTree
118
+ data: response.data.directoryTree,
119
+ user_id: response.data.user_id
115
120
  };
116
121
  }
117
122
  catch (error) {
@@ -3,6 +3,7 @@ import * as fs from 'fs';
3
3
  import * as path from 'path';
4
4
  import axios from 'axios';
5
5
  import { getProjectID } from '../helpers/helpers.js';
6
+ import { track } from '../utils/analytics.js';
6
7
  /**
7
8
  * PullFiles tool
8
9
  * - Returns a hardcoded representation of a directory structure
@@ -31,6 +32,7 @@ export async function runPullFilesTool(args) {
31
32
  try {
32
33
  const result = await fetchDirectoryStructure(fileNames, projectID, personalAccessToken);
33
34
  if (result.success) {
35
+ const userID = result.user_id;
34
36
  // Prepend workspacePath to all filePath attributes
35
37
  prepareFilePaths(result.data, workspacePath);
36
38
  // Download and save any files referenced in the response
@@ -39,10 +41,12 @@ export async function runPullFilesTool(args) {
39
41
  await checkForCodeChanges(result.data);
40
42
  // clean the directory structure
41
43
  const cleanedResult = processDirectoryStructure(result.data);
42
- // write resultJSON to a file
43
- if (process.env.DEBUG_MODE === 'true') {
44
- fs.writeFileSync('result.json', JSON.stringify(cleanedResult, null, 2));
45
- }
44
+ track('mcp_execute_tool_e', {
45
+ tool_name: pullFilesToolName,
46
+ project_id: projectID,
47
+ user_id: userID,
48
+ source: 'cursor', // TODO: update it when we release vscode extension
49
+ });
46
50
  return {
47
51
  content: [
48
52
  {
@@ -111,7 +115,8 @@ async function fetchDirectoryStructure(fileNames, projectID, personalAccessToken
111
115
  }
112
116
  return {
113
117
  success: true,
114
- data: response.data.directoryTree
118
+ data: response.data.directoryTree,
119
+ user_id: response.data.user_id
115
120
  };
116
121
  }
117
122
  catch (error) {
@@ -0,0 +1,47 @@
1
+ import { MIXPANEL_PROJECT_TOKEN, MIXPANEL_PROXY_DOMAIN } from '../constants.js';
2
+ export function track(event, props = {}) {
3
+ if (process.env.NODE_ENV === 'test' || process.env.IS_TEST === 'true') {
4
+ console.log('Analytics disabled: NODE_ENV is test or IS_TEST is true');
5
+ return;
6
+ }
7
+ if (!MIXPANEL_PROJECT_TOKEN || !MIXPANEL_PROXY_DOMAIN) {
8
+ console.log('Analytics disabled: MIXPANEL_PROJECT_TOKEN or MIXPANEL_PROXY_DOMAIN not set');
9
+ return;
10
+ }
11
+ try {
12
+ // Create the Mixpanel-compatible event object
13
+ const eventObject = {
14
+ event: event,
15
+ properties: {
16
+ ...props,
17
+ token: MIXPANEL_PROJECT_TOKEN,
18
+ time: Math.floor(Date.now() / 1000),
19
+ distinct_id: props.user_id || 'anonymous',
20
+ }
21
+ };
22
+ const encodedData = Buffer.from(JSON.stringify([eventObject])).toString('base64');
23
+ console.log(`Analytics: tracking event '${event}'`);
24
+ fetch(MIXPANEL_PROXY_DOMAIN + '/track/?data=' + encodedData, {
25
+ method: 'GET',
26
+ headers: {
27
+ 'Accept': 'text/plain'
28
+ }
29
+ })
30
+ .then(response => {
31
+ if (response.ok) { // Status code in the range 200-299
32
+ if (process.env.IS_DEV === 'true') {
33
+ console.log(`Analytics: successfully sent event '${event}' with status ${response.status}`);
34
+ }
35
+ }
36
+ else {
37
+ console.error(`Error sending event '${event}' to Mixpanel:`, response.statusText);
38
+ }
39
+ })
40
+ .catch(error => {
41
+ console.error(`Error sending event '${event}' to Mixpanel:`, error);
42
+ });
43
+ }
44
+ catch (error) {
45
+ console.error(`Error preparing event '${event}' for tracking:`, error);
46
+ }
47
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@locofy/mcp",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Locofy MCP Server with Cursor",
5
5
  "keywords": [
6
6
  "figma",