@hubspot/cli 7.5.11-experimental.0 → 7.7.0-experimental.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 (289) hide show
  1. package/bin/cli.js +5 -6
  2. package/bin/hsmcp.d.ts +2 -0
  3. package/bin/hsmcp.js +13 -0
  4. package/commands/account/auth.d.ts +3 -7
  5. package/commands/account/auth.js +19 -9
  6. package/commands/account/clean.d.ts +3 -7
  7. package/commands/account/clean.js +16 -9
  8. package/commands/account/createOverride.d.ts +3 -7
  9. package/commands/account/createOverride.js +23 -6
  10. package/commands/account/info.d.ts +3 -7
  11. package/commands/account/info.js +13 -5
  12. package/commands/account/list.d.ts +3 -7
  13. package/commands/account/list.js +15 -8
  14. package/commands/account/remove.d.ts +3 -7
  15. package/commands/account/remove.js +21 -9
  16. package/commands/account/removeOverride.d.ts +3 -7
  17. package/commands/account/removeOverride.js +23 -6
  18. package/commands/account/rename.d.ts +3 -7
  19. package/commands/account/rename.js +16 -9
  20. package/commands/account/use.d.ts +5 -9
  21. package/commands/account/use.js +14 -6
  22. package/commands/account.d.ts +3 -4
  23. package/commands/account.js +35 -58
  24. package/commands/app/migrate.d.ts +1 -2
  25. package/commands/app/migrate.js +7 -8
  26. package/commands/app/secret/add.d.ts +7 -0
  27. package/commands/app/secret/add.js +64 -0
  28. package/commands/app/secret/delete.d.ts +8 -0
  29. package/commands/app/secret/delete.js +87 -0
  30. package/commands/app/secret/list.d.ts +6 -0
  31. package/commands/app/secret/list.js +64 -0
  32. package/commands/app/secret/update.d.ts +7 -0
  33. package/commands/app/secret/update.js +77 -0
  34. package/commands/app/secret.d.ts +3 -0
  35. package/commands/app/secret.js +30 -0
  36. package/commands/app.d.ts +2 -5
  37. package/commands/app.js +12 -8
  38. package/commands/auth.d.ts +3 -7
  39. package/commands/auth.js +12 -5
  40. package/commands/cms/convertFields.d.ts +7 -1
  41. package/commands/cms/convertFields.js +57 -41
  42. package/commands/cms/getReactModule.d.ts +7 -1
  43. package/commands/cms/getReactModule.js +52 -34
  44. package/commands/cms/lighthouseScore.d.ts +8 -1
  45. package/commands/cms/lighthouseScore.js +129 -100
  46. package/commands/cms.d.ts +3 -1
  47. package/commands/cms.js +24 -15
  48. package/commands/completion.d.ts +3 -1
  49. package/commands/completion.js +25 -12
  50. package/commands/config/migrate.d.ts +3 -7
  51. package/commands/config/migrate.js +25 -15
  52. package/commands/config/set.d.ts +5 -6
  53. package/commands/config/set.js +38 -14
  54. package/commands/config.d.ts +3 -4
  55. package/commands/config.js +20 -44
  56. package/commands/create/api-sample.d.ts +3 -1
  57. package/commands/create/api-sample.js +34 -38
  58. package/commands/create/app.d.ts +3 -1
  59. package/commands/create/app.js +9 -7
  60. package/commands/create/function.d.ts +3 -1
  61. package/commands/create/function.js +11 -10
  62. package/commands/create/index.d.ts +5 -1
  63. package/commands/create/index.js +23 -11
  64. package/commands/create/module.d.ts +3 -1
  65. package/commands/create/module.js +14 -13
  66. package/commands/create/react-app.d.ts +3 -1
  67. package/commands/create/react-app.js +10 -7
  68. package/commands/create/template.d.ts +3 -1
  69. package/commands/create/template.js +14 -14
  70. package/commands/create/vue-app.d.ts +3 -1
  71. package/commands/create/vue-app.js +10 -7
  72. package/commands/create/webpack-serverless.d.ts +3 -1
  73. package/commands/create/webpack-serverless.js +10 -7
  74. package/commands/create/website-theme.d.ts +3 -1
  75. package/commands/create/website-theme.js +10 -9
  76. package/commands/create.d.ts +4 -24
  77. package/commands/create.js +64 -74
  78. package/commands/customObject/create.d.ts +4 -9
  79. package/commands/customObject/create.js +17 -10
  80. package/commands/customObject/schema/create.d.ts +4 -9
  81. package/commands/customObject/schema/create.js +18 -11
  82. package/commands/customObject/schema/delete.d.ts +4 -9
  83. package/commands/customObject/schema/delete.js +17 -10
  84. package/commands/customObject/schema/fetch-all.d.ts +4 -9
  85. package/commands/customObject/schema/fetch-all.js +17 -10
  86. package/commands/customObject/schema/fetch.d.ts +4 -9
  87. package/commands/customObject/schema/fetch.js +17 -10
  88. package/commands/customObject/schema/list.d.ts +4 -8
  89. package/commands/customObject/schema/list.js +17 -10
  90. package/commands/customObject/schema/update.d.ts +4 -9
  91. package/commands/customObject/schema/update.js +18 -11
  92. package/commands/customObject/schema.d.ts +3 -5
  93. package/commands/customObject/schema.js +27 -54
  94. package/commands/customObject.d.ts +3 -4
  95. package/commands/customObject.js +20 -45
  96. package/commands/doctor.d.ts +6 -8
  97. package/commands/doctor.js +32 -21
  98. package/commands/feedback.d.ts +4 -1
  99. package/commands/feedback.js +40 -47
  100. package/commands/fetch.d.ts +12 -1
  101. package/commands/fetch.js +49 -33
  102. package/commands/filemanager/fetch.d.ts +4 -9
  103. package/commands/filemanager/fetch.js +18 -11
  104. package/commands/filemanager/upload.d.ts +4 -9
  105. package/commands/filemanager/upload.js +17 -11
  106. package/commands/filemanager.d.ts +3 -4
  107. package/commands/filemanager.js +20 -41
  108. package/commands/function/deploy.d.ts +6 -1
  109. package/commands/function/deploy.js +70 -50
  110. package/commands/function/list.d.ts +6 -1
  111. package/commands/function/list.js +44 -32
  112. package/commands/function/server.d.ts +10 -1
  113. package/commands/function/server.js +49 -38
  114. package/commands/function.d.ts +5 -1
  115. package/commands/function.js +24 -10
  116. package/commands/hubdb/clear.d.ts +4 -9
  117. package/commands/hubdb/clear.js +17 -10
  118. package/commands/hubdb/create.d.ts +4 -9
  119. package/commands/hubdb/create.js +17 -10
  120. package/commands/hubdb/delete.d.ts +4 -9
  121. package/commands/hubdb/delete.js +17 -10
  122. package/commands/hubdb/fetch.d.ts +4 -9
  123. package/commands/hubdb/fetch.js +17 -10
  124. package/commands/hubdb.d.ts +3 -2
  125. package/commands/hubdb.js +23 -45
  126. package/commands/init.d.ts +3 -7
  127. package/commands/init.js +12 -5
  128. package/commands/lint.d.ts +6 -4
  129. package/commands/lint.js +44 -43
  130. package/commands/list.d.ts +3 -7
  131. package/commands/list.js +19 -11
  132. package/commands/logs.d.ts +10 -1
  133. package/commands/logs.js +53 -44
  134. package/commands/module/marketplace-validate.d.ts +6 -1
  135. package/commands/module/marketplace-validate.js +39 -27
  136. package/commands/module.d.ts +3 -1
  137. package/commands/module.js +22 -10
  138. package/commands/mv.d.ts +3 -7
  139. package/commands/mv.js +19 -11
  140. package/commands/open.d.ts +3 -7
  141. package/commands/open.js +19 -11
  142. package/commands/project/cloneApp.d.ts +1 -1
  143. package/commands/project/cloneApp.js +2 -2
  144. package/commands/project/create.js +3 -3
  145. package/commands/project/deploy.d.ts +1 -0
  146. package/commands/project/deploy.js +40 -12
  147. package/commands/project/dev/index.d.ts +1 -4
  148. package/commands/project/dev/index.js +48 -16
  149. package/commands/project/dev/unifiedFlow.d.ts +2 -1
  150. package/commands/project/dev/unifiedFlow.js +85 -30
  151. package/commands/project/migrate.d.ts +1 -0
  152. package/commands/project/profile/add.d.ts +7 -0
  153. package/commands/project/profile/add.js +209 -0
  154. package/commands/project/profile/delete.d.ts +6 -0
  155. package/commands/project/profile/delete.js +123 -0
  156. package/commands/project/profile.d.ts +3 -0
  157. package/commands/project/profile.js +25 -0
  158. package/commands/project/upload.d.ts +1 -0
  159. package/commands/project/upload.js +38 -8
  160. package/commands/project/validate.d.ts +4 -0
  161. package/commands/project/validate.js +53 -0
  162. package/commands/project.js +4 -0
  163. package/commands/remove.d.ts +3 -7
  164. package/commands/remove.js +19 -11
  165. package/commands/sandbox/create.d.ts +4 -9
  166. package/commands/sandbox/create.js +18 -11
  167. package/commands/sandbox/delete.d.ts +4 -9
  168. package/commands/sandbox/delete.js +18 -11
  169. package/commands/sandbox.d.ts +3 -4
  170. package/commands/sandbox.js +20 -43
  171. package/commands/secret/addSecret.d.ts +4 -9
  172. package/commands/secret/addSecret.js +17 -10
  173. package/commands/secret/deleteSecret.d.ts +4 -9
  174. package/commands/secret/deleteSecret.js +17 -10
  175. package/commands/secret/listSecret.d.ts +4 -9
  176. package/commands/secret/listSecret.js +17 -10
  177. package/commands/secret/updateSecret.d.ts +4 -9
  178. package/commands/secret/updateSecret.js +17 -10
  179. package/commands/secret.d.ts +3 -4
  180. package/commands/secret.js +25 -48
  181. package/commands/setupMcp.d.ts +8 -0
  182. package/commands/setupMcp.js +229 -0
  183. package/commands/theme/generate-selectors.d.ts +3 -7
  184. package/commands/theme/generate-selectors.js +14 -6
  185. package/commands/theme/marketplace-validate.d.ts +4 -9
  186. package/commands/theme/marketplace-validate.js +17 -10
  187. package/commands/theme/preview.d.ts +4 -9
  188. package/commands/theme/preview.js +16 -9
  189. package/commands/theme.d.ts +3 -4
  190. package/commands/theme.js +23 -46
  191. package/commands/upload.d.ts +12 -1
  192. package/commands/upload.js +118 -97
  193. package/commands/watch.d.ts +14 -1
  194. package/commands/watch.js +76 -65
  195. package/lang/en.d.ts +838 -574
  196. package/lang/en.js +630 -373
  197. package/lang/en.lyaml +30 -23
  198. package/lib/accountTypes.js +2 -1
  199. package/lib/app/migrate.d.ts +23 -0
  200. package/lib/app/migrate.js +14 -3
  201. package/lib/app/migrate_legacy.js +7 -7
  202. package/lib/app/urls.d.ts +16 -0
  203. package/lib/app/urls.js +16 -0
  204. package/lib/configMigrate.js +24 -10
  205. package/lib/configOptions.d.ts +4 -0
  206. package/lib/configOptions.js +41 -46
  207. package/lib/constants.d.ts +6 -0
  208. package/lib/constants.js +7 -1
  209. package/lib/dependencyManagement.d.ts +0 -5
  210. package/lib/dependencyManagement.js +13 -39
  211. package/lib/doctor/Doctor.js +2 -1
  212. package/lib/filesystem.d.ts +1 -1
  213. package/lib/interpolation.d.ts +2 -3
  214. package/lib/lang.d.ts +2 -3
  215. package/lib/middleware/autoUpdateMiddleware.d.ts +1 -0
  216. package/lib/middleware/autoUpdateMiddleware.js +89 -0
  217. package/lib/middleware/configMiddleware.js +8 -0
  218. package/lib/npm.d.ts +9 -0
  219. package/lib/npm.js +36 -0
  220. package/lib/projectProfiles.d.ts +6 -0
  221. package/lib/projectProfiles.js +65 -0
  222. package/lib/projects/buildAndDeploy.js +17 -2
  223. package/lib/projects/localDev/AppDevModeInterface.d.ts +26 -0
  224. package/lib/projects/localDev/AppDevModeInterface.js +156 -0
  225. package/lib/projects/localDev/DevServerManagerV2.d.ts +11 -22
  226. package/lib/projects/localDev/DevServerManagerV2.js +19 -15
  227. package/lib/projects/localDev/LocalDevLogger.d.ts +30 -0
  228. package/lib/projects/localDev/LocalDevLogger.js +158 -0
  229. package/lib/projects/localDev/LocalDevManager.js +12 -5
  230. package/lib/projects/localDev/LocalDevProcess.d.ts +27 -0
  231. package/lib/projects/localDev/LocalDevProcess.js +171 -0
  232. package/lib/projects/localDev/LocalDevState.d.ts +37 -0
  233. package/lib/projects/localDev/LocalDevState.js +78 -0
  234. package/lib/projects/localDev/LocalDevWatcher.d.ts +10 -0
  235. package/lib/projects/localDev/LocalDevWatcher.js +56 -0
  236. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +17 -0
  237. package/lib/projects/localDev/LocalDevWebsocketServer.js +92 -0
  238. package/lib/projects/localDev/helpers.d.ts +3 -2
  239. package/lib/projects/localDev/helpers.js +32 -2
  240. package/lib/projects/upload.d.ts +2 -1
  241. package/lib/projects/upload.js +2 -2
  242. package/lib/prompts/createApiSamplePrompt.d.ts +2 -10
  243. package/lib/prompts/createTemplatePrompt.d.ts +22 -4
  244. package/lib/prompts/installAppPrompt.d.ts +1 -0
  245. package/lib/prompts/installAppPrompt.js +35 -0
  246. package/lib/prompts/projectDevTargetAccountPrompt.d.ts +6 -1
  247. package/lib/prompts/projectDevTargetAccountPrompt.js +6 -6
  248. package/lib/prompts/promptUtils.d.ts +2 -1
  249. package/lib/prompts/promptUtils.js +2 -1
  250. package/lib/prompts/selectAppPrompt.d.ts +2 -0
  251. package/lib/prompts/selectAppPrompt.js +40 -0
  252. package/lib/prompts/{selectPublicAppPrompt.d.ts → selectPublicAppForMigrationPrompt.d.ts} +1 -1
  253. package/lib/prompts/{selectPublicAppPrompt.js → selectPublicAppForMigrationPrompt.js} +8 -8
  254. package/lib/testUtils.d.ts +3 -3
  255. package/lib/testUtils.js +8 -9
  256. package/lib/ui/index.js +4 -1
  257. package/lib/upload.d.ts +1 -1
  258. package/lib/validation.js +4 -5
  259. package/lib/yargsUtils.d.ts +4 -0
  260. package/lib/yargsUtils.js +6 -0
  261. package/mcp-server/index.d.ts +1 -0
  262. package/mcp-server/index.js +17 -0
  263. package/mcp-server/mcpLoader.d.ts +5 -0
  264. package/mcp-server/mcpLoader.js +24 -0
  265. package/mcp-server/tools/ExplainProjectStructureTool.d.ts +33 -0
  266. package/mcp-server/tools/ExplainProjectStructureTool.js +266 -0
  267. package/mcp-server/tools/GenerateAppComponentTool.d.ts +99 -0
  268. package/mcp-server/tools/GenerateAppComponentTool.js +193 -0
  269. package/mcp-server/tools/GenerateCardComponentTool.d.ts +74 -0
  270. package/mcp-server/tools/GenerateCardComponentTool.js +146 -0
  271. package/mcp-server/tools/GenerateProjectConfigTool.d.ts +32 -0
  272. package/mcp-server/tools/GenerateProjectConfigTool.js +40 -0
  273. package/mcp-server/tools/HubSpotCLIHelper.d.ts +16 -0
  274. package/mcp-server/tools/HubSpotCLIHelper.js +74 -0
  275. package/mcp-server/tools/UploadProjectTool.d.ts +44 -0
  276. package/mcp-server/tools/UploadProjectTool.js +149 -0
  277. package/mcp-server/tools/ValidateProjectTool.d.ts +62 -0
  278. package/mcp-server/tools/ValidateProjectTool.js +315 -0
  279. package/package.json +13 -6
  280. package/types/Cms.d.ts +30 -0
  281. package/types/Cms.js +2 -0
  282. package/types/LocalDev.d.ts +24 -0
  283. package/types/LocalDev.js +2 -0
  284. package/types/Prompts.d.ts +0 -7
  285. package/types/Yargs.d.ts +8 -1
  286. package/lib/projects/localDev/LocalDevManagerV2.d.ts +0 -64
  287. package/lib/projects/localDev/LocalDevManagerV2.js +0 -345
  288. package/lib/prompts/installPublicAppPrompt.d.ts +0 -1
  289. package/lib/prompts/installPublicAppPrompt.js +0 -41
@@ -0,0 +1,149 @@
1
+ import { MCPTool } from "mcp-framework";
2
+ import { z } from "zod";
3
+ import HubSpotCLIHelper from "./HubSpotCLIHelper.js";
4
+ class UploadProjectTool extends MCPTool {
5
+ name = "uploadProject";
6
+ description = "Uploads a developer project to HubSpot using the HubSpot CLI";
7
+ cliHelper = new HubSpotCLIHelper();
8
+ schema = {
9
+ projectPath: {
10
+ type: z.string().optional(),
11
+ description: "Path to the project directory. Defaults to current directory",
12
+ },
13
+ accountId: {
14
+ type: z.string().optional(),
15
+ description: "HubSpot account ID to upload to. If not provided, uses CLI default or prompts",
16
+ },
17
+ autoInstallCLI: {
18
+ type: z.boolean().optional(),
19
+ description: "Whether to automatically install HubSpot CLI if not found. Defaults to false",
20
+ },
21
+ };
22
+ async execute(input) {
23
+ const { projectPath = ".", accountId, autoInstallCLI = false } = input;
24
+ try {
25
+ // Step 1: Check if HubSpot CLI is installed
26
+ const cliCheckResult = await this.cliHelper.checkCLIInstallation();
27
+ if (!cliCheckResult.isInstalled) {
28
+ if (autoInstallCLI) {
29
+ // Attempt to install CLI automatically
30
+ const installResult = await this.cliHelper.installCLI();
31
+ if (!installResult.success) {
32
+ return {
33
+ status: "cli-install-failed",
34
+ message: "❌ Failed to install HubSpot CLI automatically",
35
+ error: installResult.error,
36
+ actions: [
37
+ {
38
+ action: "install-cli-manually",
39
+ command: "npm install -g @hubspot/cli",
40
+ description: "Install HubSpot CLI manually",
41
+ },
42
+ ],
43
+ troubleshooting: [
44
+ "Try installing the CLI manually: npm install -g @hubspot/cli",
45
+ "Ensure you have npm installed and proper permissions",
46
+ "Run the upload command again after CLI installation",
47
+ ],
48
+ };
49
+ }
50
+ // Verify installation was successful
51
+ const recheckResult = await this.cliHelper.checkCLIInstallation();
52
+ if (!recheckResult.isInstalled) {
53
+ return {
54
+ status: "cli-install-verification-failed",
55
+ message: "❌ CLI installation completed but verification failed",
56
+ troubleshooting: [
57
+ "Try running 'hs --version' manually to verify installation",
58
+ "Restart your terminal/shell session",
59
+ "Check if the CLI was installed to the correct PATH",
60
+ ],
61
+ };
62
+ }
63
+ }
64
+ else {
65
+ return {
66
+ status: "cli-not-found",
67
+ message: "HubSpot CLI not found. Install it to upload projects.",
68
+ actions: [
69
+ {
70
+ action: "install-cli",
71
+ command: "npm install -g @hubspot/cli",
72
+ description: "Install HubSpot CLI globally",
73
+ },
74
+ ],
75
+ nextSteps: [
76
+ "1. Install HubSpot CLI globally",
77
+ "2. Authenticate with your HubSpot account (hs auth)",
78
+ "3. Run project upload again",
79
+ ],
80
+ };
81
+ }
82
+ }
83
+ // Step 2: Build the upload command
84
+ let uploadCommand = "hs project upload";
85
+ if (accountId) {
86
+ uploadCommand += ` --account=${accountId}`;
87
+ }
88
+ // Step 3: Run project upload
89
+ const uploadResult = await this.cliHelper.runProjectCommand(uploadCommand, projectPath);
90
+ if (uploadResult.success) {
91
+ // Parse successful upload output
92
+ const output = uploadResult.output;
93
+ return {
94
+ status: "success",
95
+ message: "✅ Project uploaded successfully to HubSpot!",
96
+ cliVersion: cliCheckResult.version,
97
+ uploadOutput: output,
98
+ accountId: accountId,
99
+ projectPath: projectPath,
100
+ nextSteps: [
101
+ "1. Check your HubSpot account to verify the project appears",
102
+ "2. Test your components in the HubSpot environment",
103
+ "3. Monitor for any runtime errors or issues",
104
+ "4. Use 'hs project logs' to view application logs if needed",
105
+ ],
106
+ };
107
+ }
108
+ else {
109
+ // Parse upload failure
110
+ const errorOutput = uploadResult.output || uploadResult.error || "Upload failed";
111
+ return {
112
+ status: "upload-failed",
113
+ message: "❌ Project upload failed",
114
+ cliVersion: cliCheckResult.version,
115
+ uploadOutput: errorOutput,
116
+ error: uploadResult.error,
117
+ troubleshooting: [
118
+ "Ensure you're authenticated: run 'hs auth' to login",
119
+ "Verify your account has permission to upload projects",
120
+ "Check that your project is valid: run 'hs project validate' first",
121
+ "Ensure you have network connectivity to HubSpot",
122
+ "Try uploading to a different account if you have access to multiple",
123
+ ],
124
+ nextSteps: [
125
+ "1. Check authentication status: hs auth info",
126
+ "2. Validate project first: hs project validate",
127
+ "3. Review the error output above for specific issues",
128
+ "4. Try the upload command again after fixing issues",
129
+ ],
130
+ };
131
+ }
132
+ }
133
+ catch (error) {
134
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
135
+ return {
136
+ status: "error",
137
+ message: "An error occurred during project upload",
138
+ error: errorMessage,
139
+ troubleshooting: [
140
+ "Ensure you're in a valid developer project directory",
141
+ "Check that hsproject.json exists in the project root",
142
+ "Verify HubSpot CLI is properly installed and accessible",
143
+ "Try running 'hs project upload' manually to see detailed output",
144
+ ],
145
+ };
146
+ }
147
+ }
148
+ }
149
+ export default UploadProjectTool;
@@ -0,0 +1,62 @@
1
+ import { MCPTool } from "mcp-framework";
2
+ import { z } from "zod";
3
+ interface ValidateProjectInput {
4
+ autoFix?: boolean;
5
+ projectPath?: string;
6
+ }
7
+ interface ValidationResponse {
8
+ status: string;
9
+ message: string;
10
+ cliVersion?: string;
11
+ validationOutput?: string;
12
+ errors?: string[];
13
+ errorAnalysis?: Array<{
14
+ category: string;
15
+ issue: string;
16
+ severity: "error" | "warning";
17
+ component?: string;
18
+ file?: string;
19
+ }>;
20
+ suggestions?: string[];
21
+ nextSteps?: string[];
22
+ autoFixActions?: Array<{
23
+ action: string;
24
+ description: string;
25
+ command?: string;
26
+ tool?: string;
27
+ }>;
28
+ actions?: Array<{
29
+ action: string;
30
+ command: string;
31
+ description: string;
32
+ }>;
33
+ projectStructure?: string;
34
+ error?: string;
35
+ troubleshooting?: string[];
36
+ }
37
+ declare class ValidateProjectTool extends MCPTool<ValidateProjectInput> {
38
+ name: string;
39
+ description: string;
40
+ private cliHelper;
41
+ schema: {
42
+ autoFix: {
43
+ type: z.ZodOptional<z.ZodBoolean>;
44
+ description: string;
45
+ };
46
+ projectPath: {
47
+ type: z.ZodOptional<z.ZodString>;
48
+ description: string;
49
+ };
50
+ };
51
+ execute(input: ValidateProjectInput): Promise<ValidationResponse>;
52
+ private runProjectValidation;
53
+ private runCommand;
54
+ private parseValidationErrors;
55
+ private analyzeValidationErrors;
56
+ private extractComponentFromPath;
57
+ private generateFixSuggestions;
58
+ private extractFieldFromError;
59
+ private generateNextSteps;
60
+ private generateAutoFixActions;
61
+ }
62
+ export default ValidateProjectTool;
@@ -0,0 +1,315 @@
1
+ import { MCPTool } from "mcp-framework";
2
+ import { z } from "zod";
3
+ import HubSpotCLIHelper from "./HubSpotCLIHelper.js";
4
+ class ValidateProjectTool extends MCPTool {
5
+ name = "validateProject";
6
+ description = "Validates a developer project using the HubSpot CLI and provides guidance for fixing any validation errors";
7
+ cliHelper = new HubSpotCLIHelper();
8
+ schema = {
9
+ autoFix: {
10
+ type: z.boolean().optional(),
11
+ description: "Whether to attempt automatic fixes for common validation errors. Defaults to false",
12
+ },
13
+ projectPath: {
14
+ type: z.string().optional(),
15
+ description: "Path to the project directory. Defaults to current directory",
16
+ },
17
+ };
18
+ async execute(input) {
19
+ const { autoFix = false, projectPath = "." } = input;
20
+ try {
21
+ // Step 1: Check if HubSpot CLI is installed
22
+ const cliCheckResult = await this.cliHelper.checkCLIInstallation();
23
+ if (!cliCheckResult.isInstalled) {
24
+ return {
25
+ status: "cli-not-found",
26
+ message: "HubSpot CLI not found. Installing...",
27
+ actions: [
28
+ {
29
+ action: "install-cli",
30
+ command: "npm install -g @hubspot/cli",
31
+ description: "Installing HubSpot CLI globally",
32
+ },
33
+ ],
34
+ nextSteps: [
35
+ "1. Install HubSpot CLI globally",
36
+ "2. Run project validation again",
37
+ "3. Follow any additional guidance for fixing validation errors",
38
+ ],
39
+ };
40
+ }
41
+ // Step 2: Run project validation
42
+ const validationResult = await this.runProjectValidation(projectPath);
43
+ if (validationResult.isValid) {
44
+ return {
45
+ status: "valid",
46
+ message: "✅ Project validation passed! Your developer project is properly configured.",
47
+ cliVersion: cliCheckResult.version,
48
+ validationOutput: validationResult.output,
49
+ projectStructure: "All components and configurations follow platform conventions",
50
+ };
51
+ }
52
+ // Step 3: Parse validation errors and provide guidance
53
+ const errorAnalysis = this.analyzeValidationErrors(validationResult.errors);
54
+ const suggestions = this.generateFixSuggestions(errorAnalysis);
55
+ const response = {
56
+ status: "validation-failed",
57
+ message: "❌ Project validation failed. Here's how to fix the issues:",
58
+ cliVersion: cliCheckResult.version,
59
+ validationOutput: validationResult.output,
60
+ errors: validationResult.errors,
61
+ errorAnalysis: errorAnalysis,
62
+ suggestions: suggestions,
63
+ nextSteps: this.generateNextSteps(errorAnalysis, autoFix),
64
+ };
65
+ if (autoFix) {
66
+ response.autoFixActions = this.generateAutoFixActions(errorAnalysis);
67
+ }
68
+ return response;
69
+ }
70
+ catch (error) {
71
+ const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
72
+ return {
73
+ status: "error",
74
+ message: "An error occurred during project validation",
75
+ error: errorMessage,
76
+ troubleshooting: [
77
+ "Ensure you're in a valid developer project directory",
78
+ "Check that hsproject.json exists in the project root",
79
+ "Verify HubSpot CLI is properly installed and accessible",
80
+ "Try running 'hs project validate' manually to see detailed output",
81
+ ],
82
+ };
83
+ }
84
+ }
85
+ async runProjectValidation(projectPath) {
86
+ try {
87
+ const result = await this.cliHelper.runProjectCommand("hs project validate", projectPath);
88
+ if (result.success) {
89
+ // Parse the validation output to determine if it passed
90
+ const output = result.output;
91
+ // Check for validation success indicators
92
+ const isValid = output.includes("✅") ||
93
+ output.includes("Project validation passed") ||
94
+ output.includes("valid") ||
95
+ !output.includes("Project validation failed:");
96
+ // Parse structured validation errors if present
97
+ const errors = [];
98
+ if (!isValid && output.includes("Project validation failed:")) {
99
+ errors.push(...this.parseValidationErrors(output));
100
+ }
101
+ return {
102
+ isValid: isValid,
103
+ output: output,
104
+ errors: errors,
105
+ };
106
+ }
107
+ else {
108
+ // Command failed to run
109
+ const errorMessage = result.error || "Failed to run project validation";
110
+ return {
111
+ isValid: false,
112
+ output: result.output || "",
113
+ errors: [errorMessage],
114
+ };
115
+ }
116
+ }
117
+ catch (error) {
118
+ const errorMessage = error instanceof Error ? error.message : "Unknown validation error";
119
+ throw new Error(`Failed to run project validation: ${errorMessage}`);
120
+ }
121
+ }
122
+ runCommand(command) {
123
+ // Delegate to the CLI helper
124
+ return this.cliHelper.runCommand(command);
125
+ }
126
+ parseValidationErrors(output) {
127
+ const errors = [];
128
+ const lines = output.split("\n");
129
+ let currentFile = "";
130
+ let inErrorSection = false;
131
+ for (const line of lines) {
132
+ // Look for file error headers like "Encountered the following errors for src/app/file.json:"
133
+ const fileMatch = line.match(/Encountered the following errors for (.+?):/);
134
+ if (fileMatch) {
135
+ currentFile = fileMatch[1];
136
+ inErrorSection = true;
137
+ continue;
138
+ }
139
+ // Parse individual error lines (start with tab and dash)
140
+ if (inErrorSection && line.match(/^\s*-\s+/)) {
141
+ const errorText = line.replace(/^\s*-\s+/, "").trim();
142
+ if (errorText) {
143
+ errors.push(`${currentFile}: ${errorText}`);
144
+ }
145
+ continue;
146
+ }
147
+ // Handle multi-line errors with additional indentation
148
+ if (inErrorSection && line.match(/^\s{2,}-\s+/)) {
149
+ const errorText = line.replace(/^\s*-\s+/, "").trim();
150
+ if (errorText && errors.length > 0) {
151
+ // Append to the last error as additional context
152
+ errors[errors.length - 1] += `\n ${errorText}`;
153
+ }
154
+ continue;
155
+ }
156
+ // Reset when we hit an empty line or new section
157
+ if (line.trim() === "" ||
158
+ (!line.startsWith("\t") && !line.startsWith(" "))) {
159
+ inErrorSection = false;
160
+ currentFile = "";
161
+ }
162
+ }
163
+ return errors;
164
+ }
165
+ analyzeValidationErrors(errors) {
166
+ const analysis = [];
167
+ for (const error of errors) {
168
+ const filePath = error.split(":")[0];
169
+ const errorMessage = error.substring(error.indexOf(":") + 1).trim();
170
+ let category = "unknown";
171
+ let component = "unknown";
172
+ let severity = "error";
173
+ // Extract file information
174
+ if (filePath.includes("hsproject.json")) {
175
+ category = "project-config";
176
+ component = "project";
177
+ }
178
+ else if (filePath.includes("-hsmeta.json")) {
179
+ category = "component-config";
180
+ component = this.extractComponentFromPath(filePath);
181
+ }
182
+ else if (filePath.includes("package.json")) {
183
+ category = "dependencies";
184
+ component = this.extractComponentFromPath(filePath);
185
+ severity = "warning";
186
+ }
187
+ // Analyze error message content
188
+ if (errorMessage.includes("Invalid JSON")) {
189
+ category = "json-syntax";
190
+ }
191
+ else if (errorMessage.includes("Missing required field")) {
192
+ category = "required-field";
193
+ }
194
+ else if (errorMessage.includes("must NOT have additional properties")) {
195
+ category = "schema-validation";
196
+ }
197
+ else if (errorMessage.includes("entrypoint")) {
198
+ category = "entrypoint";
199
+ }
200
+ analysis.push({
201
+ category: category,
202
+ issue: errorMessage,
203
+ severity: severity,
204
+ component: component,
205
+ file: filePath,
206
+ });
207
+ }
208
+ return analysis;
209
+ }
210
+ extractComponentFromPath(filePath) {
211
+ // Extract component type from file path like "src/app/cards/my-card-hsmeta.json"
212
+ if (filePath.includes("/app/")) {
213
+ const pathParts = filePath.split("/app/")[1].split("/");
214
+ if (pathParts.length > 1) {
215
+ return pathParts[0]; // e.g., "cards", "functions", etc.
216
+ }
217
+ return "app";
218
+ }
219
+ // Handle top-level app component files
220
+ if (filePath.includes("-hsmeta.json")) {
221
+ return "app";
222
+ }
223
+ return "unknown";
224
+ }
225
+ generateFixSuggestions(errorAnalysis) {
226
+ const suggestions = [];
227
+ for (const error of errorAnalysis) {
228
+ switch (error.category) {
229
+ case "project-config":
230
+ suggestions.push("Fix hsproject.json: Ensure it contains 'name', 'srcDir', and 'platformVersion' fields", "Use the generateProjectConfig tool to create a valid hsproject.json file");
231
+ break;
232
+ case "component-config":
233
+ suggestions.push(`Fix ${error.component} component: Check the *-hsmeta.json file structure`, "Ensure the component follows the envelope pattern: uid, type, config", `Use the appropriate generate component tool for ${error.component} type`);
234
+ break;
235
+ case "json-syntax":
236
+ suggestions.push(`Fix JSON syntax error in ${error.file}`, "Check for missing commas, brackets, or quotes in the JSON file", "Use a JSON validator to identify the specific syntax issue");
237
+ break;
238
+ case "required-field":
239
+ suggestions.push(`Add missing required field: ${this.extractFieldFromError(error.issue)}`, `Update ${error.file} to include all required fields`, "Refer to the platform documentation for required field specifications");
240
+ break;
241
+ case "schema-validation":
242
+ suggestions.push(`Fix schema validation error in ${error.file}`, "Remove additional properties that are not allowed", `Check ${error.component} component schema requirements`, "Ensure all field types match the expected schema");
243
+ break;
244
+ case "dependencies":
245
+ suggestions.push("Fix package.json: Ensure React and @hubspot/ui-extensions dependencies are present", "Run 'npm install' to install missing dependencies", "Check that package.json is in the correct component directory");
246
+ break;
247
+ case "entrypoint":
248
+ suggestions.push("Fix component entrypoint: Ensure the React file exists at the specified path", "Check that the entrypoint path in *-hsmeta.json matches the actual file location", "Verify the React component exports properly");
249
+ break;
250
+ default:
251
+ suggestions.push(`Review error in ${error.file || "project"}: ${error.issue}`);
252
+ }
253
+ }
254
+ return [...new Set(suggestions)]; // Remove duplicates
255
+ }
256
+ extractFieldFromError(errorMessage) {
257
+ // Extract field name from messages like "Missing required field: config.description"
258
+ const match = errorMessage.match(/Missing required field:\s*(.+)/);
259
+ return match ? match[1] : "unknown field";
260
+ }
261
+ generateNextSteps(errorAnalysis, autoFix) {
262
+ const steps = [];
263
+ if (autoFix) {
264
+ steps.push("1. Review auto-fix actions and apply them");
265
+ }
266
+ else {
267
+ steps.push("1. Review the validation errors and suggestions above");
268
+ }
269
+ const hasProjectConfig = errorAnalysis.some((e) => e.category === "project-config");
270
+ const hasComponentIssues = errorAnalysis.some((e) => e.category === "component-config");
271
+ const hasDependencyIssues = errorAnalysis.some((e) => e.category === "dependencies");
272
+ if (hasProjectConfig) {
273
+ steps.push("2. Fix hsproject.json configuration issues first");
274
+ }
275
+ if (hasComponentIssues) {
276
+ steps.push("3. Fix component configuration issues");
277
+ }
278
+ if (hasDependencyIssues) {
279
+ steps.push("4. Install missing dependencies");
280
+ }
281
+ steps.push("5. Run validation again to verify fixes");
282
+ steps.push("6. Test your components work correctly in development");
283
+ return steps;
284
+ }
285
+ generateAutoFixActions(errorAnalysis) {
286
+ const actions = [];
287
+ for (const error of errorAnalysis) {
288
+ switch (error.category) {
289
+ case "project-config":
290
+ actions.push({
291
+ action: "fix-project-config",
292
+ description: "Generate valid hsproject.json configuration",
293
+ tool: "generateProjectConfig",
294
+ });
295
+ break;
296
+ case "dependencies":
297
+ actions.push({
298
+ action: "install-dependencies",
299
+ description: "Install missing npm dependencies",
300
+ command: "npm install",
301
+ });
302
+ break;
303
+ case "component-config":
304
+ actions.push({
305
+ action: "fix-component-config",
306
+ description: `Fix ${error.component} component configuration`,
307
+ tool: `generate${error.component}Component`,
308
+ });
309
+ break;
310
+ }
311
+ }
312
+ return actions;
313
+ }
314
+ }
315
+ export default ValidateProjectTool;
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "7.5.11-experimental.0",
3
+ "version": "7.7.0-experimental.0",
4
4
  "description": "The official CLI for developing on HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/HubSpot/hubspot-cli",
7
7
  "dependencies": {
8
- "@hubspot/local-dev-lib": "3.5.5",
9
- "@hubspot/project-parsing-lib": "0.0.20-experimental.0",
8
+ "@hubspot/local-dev-lib": "3.7.0",
9
+ "@hubspot/project-parsing-lib": "0.2.0",
10
10
  "@hubspot/serverless-dev-runtime": "7.0.2",
11
11
  "@hubspot/theme-preview-dev-server": "0.0.10",
12
12
  "@hubspot/ui-extensions-dev-server": "0.8.52",
13
+ "@modelcontextprotocol/sdk": "^1.12.1",
13
14
  "archiver": "7.0.1",
14
15
  "boxen": "8.0.1",
15
16
  "chalk": "4.1.2",
@@ -21,6 +22,7 @@
21
22
  "fs-extra": "8.1.0",
22
23
  "inquirer": "8.2.0",
23
24
  "js-yaml": "4.1.0",
25
+ "mcp-framework": "^0.2.2",
24
26
  "moment": "2.30.1",
25
27
  "open": "7.4.2",
26
28
  "p-queue": "6.6.2",
@@ -28,6 +30,7 @@
28
30
  "table": "6.9.0",
29
31
  "tmp": "0.2.3",
30
32
  "update-notifier": "5.1.0",
33
+ "ws": "^8.18.2",
31
34
  "yargs": "17.7.2",
32
35
  "yargs-parser": "21.1.1"
33
36
  },
@@ -41,6 +44,7 @@
41
44
  "@types/js-yaml": "^4.0.9",
42
45
  "@types/semver": "^7.5.8",
43
46
  "@types/tmp": "^0.2.6",
47
+ "@types/ws": "^8.18.1",
44
48
  "@types/yargs": "^17.0.33",
45
49
  "@typescript-eslint/eslint-plugin": "^8.30.1",
46
50
  "@typescript-eslint/parser": "^8.11.0",
@@ -63,10 +67,12 @@
63
67
  },
64
68
  "scripts": {
65
69
  "build": "ts-node ./scripts/build.ts",
66
- "lint": "eslint . && prettier --list-different './**/*.{ts,js,json}'",
70
+ "lint": "echo 'Linting is disabled for Blazar'",
71
+ "lint:local": "eslint . && prettier --list-different './**/*.{ts,js,json}'",
67
72
  "list-all-commands": "yarn ts-node ./scripts/get-all-commands.ts",
73
+ "local-link": "yarn ts-node ./scripts/linking.ts",
68
74
  "prettier:write": "prettier --write './**/*.{ts,js,json}'",
69
- "test": "yarn node --experimental-vm-modules $(yarn bin jest)",
75
+ "test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js",
70
76
  "test-cli": "yarn build && yarn --cwd 'acceptance-tests' test-ci",
71
77
  "test-cli-debug": "yarn build && yarn --cwd 'acceptance-tests' test-debug",
72
78
  "test-cli-qa": "yarn build && yarn --cwd 'acceptance-tests' test-qa",
@@ -94,7 +100,8 @@
94
100
  },
95
101
  "bin": {
96
102
  "hs": "./bin/hs",
97
- "hscms": "./bin/hscms"
103
+ "hscms": "./bin/hscms",
104
+ "hsmcp": "./bin/hsmcp.js"
98
105
  },
99
106
  "publishConfig": {
100
107
  "access": "public",
package/types/Cms.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { CommonArgs, ConfigArgs } from './Yargs';
2
+ export type CreateArgs = CommonArgs & ConfigArgs & {
3
+ branch?: string;
4
+ type: string;
5
+ dest: string;
6
+ name: string;
7
+ internal?: boolean;
8
+ };
9
+ export type CmsAssetOperationArgs = {
10
+ assetType: string;
11
+ name: string;
12
+ dest: string;
13
+ getInternalVersion: boolean;
14
+ commandArgs: CreateArgs;
15
+ };
16
+ export type CreatableCmsAsset = {
17
+ hidden: boolean;
18
+ dest: (args: CmsAssetOperationArgs) => string;
19
+ validate?: (args: CmsAssetOperationArgs) => boolean;
20
+ execute: (args: CmsAssetOperationArgs) => Promise<void>;
21
+ };
22
+ export type ApiSampleChoice = {
23
+ name: string;
24
+ description: string;
25
+ id: string;
26
+ languages: string[];
27
+ };
28
+ export type ApiSampleConfig = {
29
+ samples: ApiSampleChoice[];
30
+ };
package/types/Cms.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,24 @@
1
+ import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
2
+ import { Build } from '@hubspot/local-dev-lib/types/Build';
3
+ import { Environment } from '@hubspot/local-dev-lib/types/Config';
4
+ import { ProjectConfig } from './Projects';
5
+ import LocalDevState from '../lib/projects/localDev/LocalDevState';
6
+ export type LocalDevStateConstructorOptions = {
7
+ targetProjectAccountId: number;
8
+ targetTestingAccountId: number;
9
+ projectConfig: ProjectConfig;
10
+ projectDir: string;
11
+ projectId: number;
12
+ debug?: boolean;
13
+ deployedBuild?: Build;
14
+ isGithubLinked: boolean;
15
+ initialProjectNodes: {
16
+ [key: string]: IntermediateRepresentationNodeLocalDev;
17
+ };
18
+ env: Environment;
19
+ };
20
+ export type LocalDevWebsocketMessage = {
21
+ type: string;
22
+ data: unknown;
23
+ };
24
+ export type LocalDevStateListener<K extends keyof LocalDevState> = (value: LocalDevState[K]) => void;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +1,3 @@
1
- import { DeveloperTestAccount } from '@hubspot/local-dev-lib/types/developerTestAccounts';
2
1
  export type GenericPromptResponse = {
3
2
  [key: string]: any;
4
3
  };
@@ -23,10 +22,4 @@ export type PromptConfig<T extends GenericPromptResponse> = {
23
22
  mask?: string;
24
23
  filter?: (input: string) => string;
25
24
  };
26
- export type ProjectDevTargetAccountPromptResponse = {
27
- targetAccountId: number | null;
28
- createNestedAccount: boolean;
29
- parentAccountId?: number | null;
30
- notInConfigAccount?: DeveloperTestAccount | null;
31
- };
32
25
  export {};