@hubspot/cli 7.7.34-experimental.0 → 7.8.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 (74) hide show
  1. package/bin/cli.js +2 -0
  2. package/commands/app.js +1 -6
  3. package/commands/getStarted.d.ts +1 -1
  4. package/commands/getStarted.js +16 -64
  5. package/commands/getStartedV2.d.ts +9 -0
  6. package/commands/getStartedV2.js +39 -0
  7. package/commands/project/dev/unifiedFlow.js +1 -1
  8. package/commands/project/migrate.js +14 -4
  9. package/commands/project/upload.d.ts +2 -2
  10. package/commands/project/upload.js +1 -1
  11. package/commands/testAccount/create.js +0 -3
  12. package/lang/en.d.ts +1 -23
  13. package/lang/en.js +1 -23
  14. package/lib/__tests__/hasFeature.test.js +7 -145
  15. package/lib/constants.d.ts +0 -1
  16. package/lib/constants.js +0 -1
  17. package/lib/dependencyManagement.d.ts +5 -0
  18. package/lib/dependencyManagement.js +9 -0
  19. package/lib/hasFeature.js +0 -6
  20. package/lib/mcp/setup.js +1 -1
  21. package/lib/projectProfiles.d.ts +1 -1
  22. package/lib/projectProfiles.js +2 -10
  23. package/lib/projects/create/v3.js +2 -3
  24. package/lib/projects/localDev/helpers/project.d.ts +2 -2
  25. package/lib/projects/localDev/helpers/project.js +6 -5
  26. package/lib/projects/structure.d.ts +2 -2
  27. package/lib/projects/upload.d.ts +1 -2
  28. package/lib/projects/upload.js +0 -1
  29. package/lib/ui/SpinniesManager.js +8 -105
  30. package/mcp-server/tools/cms/HsCreateFunctionTool.js +1 -1
  31. package/mcp-server/tools/cms/HsCreateModuleTool.js +1 -1
  32. package/mcp-server/tools/cms/HsCreateTemplateTool.js +1 -1
  33. package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -2
  34. package/mcp-server/tools/cms/HsListFunctionsTool.js +1 -1
  35. package/mcp-server/tools/cms/HsListTool.js +1 -1
  36. package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +1 -1
  37. package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +1 -1
  38. package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +1 -1
  39. package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +2 -2
  40. package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +1 -1
  41. package/mcp-server/tools/cms/__tests__/HsListTool.test.js +1 -1
  42. package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
  43. package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
  44. package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
  45. package/mcp-server/tools/project/CreateProjectTool.js +5 -5
  46. package/mcp-server/tools/project/DeployProjectTool.js +1 -1
  47. package/mcp-server/tools/project/DocFetchTool.js +2 -2
  48. package/mcp-server/tools/project/DocsSearchTool.js +2 -2
  49. package/mcp-server/tools/project/GetConfigValuesTool.js +1 -1
  50. package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
  51. package/mcp-server/tools/project/UploadProjectTools.js +2 -2
  52. package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
  53. package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
  54. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
  55. package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
  56. package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +2 -2
  57. package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +2 -2
  58. package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +1 -1
  59. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
  60. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
  61. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
  62. package/mcp-server/tools/project/constants.d.ts +1 -1
  63. package/mcp-server/tools/project/constants.js +3 -9
  64. package/package.json +7 -2
  65. package/types/Yargs.d.ts +1 -1
  66. package/ui/components/Ascii.d.ts +10 -0
  67. package/ui/components/Ascii.js +11 -0
  68. package/ui/components/HorizontalSelectPrompt.js +1 -1
  69. package/ui/views/GetStarted.d.ts +7 -0
  70. package/ui/views/GetStarted.js +157 -0
  71. package/commands/app/__tests__/install.test.d.ts +0 -1
  72. package/commands/app/__tests__/install.test.js +0 -47
  73. package/commands/app/install.d.ts +0 -8
  74. package/commands/app/install.js +0 -122
package/lib/hasFeature.js CHANGED
@@ -1,13 +1,7 @@
1
1
  import { http } from '@hubspot/local-dev-lib/http';
2
2
  import { fetchEnabledFeatures } from '@hubspot/local-dev-lib/api/localDevAuth';
3
- import { FEATURES } from './constants.js';
4
- const FEATURES_THAT_DEFAULT_ON = [FEATURES.APPS_HOME];
5
3
  export async function hasFeature(accountId, feature) {
6
4
  const { data: { enabledFeatures }, } = await fetchEnabledFeatures(accountId);
7
- if (enabledFeatures[feature] === undefined &&
8
- FEATURES_THAT_DEFAULT_ON.includes(feature)) {
9
- return true;
10
- }
11
5
  return Boolean(enabledFeatures[feature]);
12
6
  }
13
7
  export async function hasUnfiedAppsAccess(accountId) {
package/lib/mcp/setup.js CHANGED
@@ -8,7 +8,7 @@ import path from 'path';
8
8
  import os from 'os';
9
9
  import fs from 'fs-extra';
10
10
  import { existsSync } from 'fs';
11
- const mcpServerName = 'HubSpot';
11
+ const mcpServerName = 'hubspot-cli-mcp';
12
12
  const claudeCode = 'claude';
13
13
  const windsurf = 'windsurf';
14
14
  const cursor = 'cursor';
@@ -4,4 +4,4 @@ export declare function logProfileHeader(profileName: string): void;
4
4
  export declare function logProfileFooter(profile: HsProfileFile, includeVariables?: boolean): void;
5
5
  export declare function loadProfile(projectConfig: ProjectConfig | null, projectDir: string | null, profileName: string): HsProfileFile | undefined;
6
6
  export declare function exitIfUsingProfiles(projectConfig: ProjectConfig | null, projectDir: string | null): Promise<void>;
7
- export declare function loadAndValidateProfile(projectConfig: ProjectConfig | null, projectDir: string | null, argsProfile: string | undefined, useEnv?: boolean): Promise<number | undefined>;
7
+ export declare function loadAndValidateProfile(projectConfig: ProjectConfig | null, projectDir: string | null, argsProfile: string | undefined): Promise<number | undefined>;
@@ -38,12 +38,7 @@ export function loadProfile(projectConfig, projectDir, profileName) {
38
38
  uiLogger.error(lib.projectProfiles.loadProfile.errors.missingAccountId(profileFilename));
39
39
  return;
40
40
  }
41
- return {
42
- ...profile,
43
- accountId: process.env.HUBSPOT_ACCOUNT_ID
44
- ? Number(process.env.HUBSPOT_ACCOUNT_ID)
45
- : profile.accountId,
46
- };
41
+ return profile;
47
42
  }
48
43
  catch (e) {
49
44
  uiLogger.error(lib.projectProfiles.loadProfile.errors.failedToLoadProfile(profileFilename));
@@ -59,7 +54,7 @@ export async function exitIfUsingProfiles(projectConfig, projectDir) {
59
54
  }
60
55
  }
61
56
  }
62
- export async function loadAndValidateProfile(projectConfig, projectDir, argsProfile, useEnv = false) {
57
+ export async function loadAndValidateProfile(projectConfig, projectDir, argsProfile) {
63
58
  if (argsProfile) {
64
59
  logProfileHeader(argsProfile);
65
60
  const profile = loadProfile(projectConfig, projectDir, argsProfile);
@@ -68,9 +63,6 @@ export async function loadAndValidateProfile(projectConfig, projectDir, argsProf
68
63
  process.exit(EXIT_CODES.ERROR);
69
64
  }
70
65
  logProfileFooter(profile, true);
71
- if (useEnv) {
72
- return Number(process.env.HUBSPOT_ACCOUNT_ID);
73
- }
74
66
  return profile.accountId;
75
67
  }
76
68
  else {
@@ -9,7 +9,7 @@ import { getConfigForPlatformVersion } from './legacy.js';
9
9
  import { logError } from '../../errorHandlers/index.js';
10
10
  import { EXIT_CODES } from '../../enums/exitCodes.js';
11
11
  import { hasFeature } from '../../hasFeature.js';
12
- import { AppEventsKey, PagesKey, } from '@hubspot/project-parsing-lib/src/lib/constants.js';
12
+ import { AppEventsKey } from '@hubspot/project-parsing-lib/src/lib/constants.js';
13
13
  export async function createV3App(providedAuth, providedDistribution) {
14
14
  let authType;
15
15
  if (providedAuth &&
@@ -51,7 +51,6 @@ export async function createV3App(providedAuth, providedDistribution) {
51
51
  }
52
52
  const componentTypeToGateMap = {
53
53
  [AppEventsKey]: FEATURES.APP_EVENTS,
54
- [PagesKey]: FEATURES.APPS_HOME,
55
54
  };
56
55
  export async function calculateComponentTemplateChoices(components, authType, distribution, accountId, projectMetadata) {
57
56
  const enabledComponents = [];
@@ -89,7 +88,7 @@ export async function calculateComponentTemplateChoices(components, authType, di
89
88
  }
90
89
  if (disabledReasons.length > 0) {
91
90
  disabledComponents.push({
92
- name: `[${chalk.yellow('DISABLED')}] ${template.label} -`,
91
+ name: `[${chalk.yellow('DISABLED')}] ${template.label}`,
93
92
  value: template,
94
93
  disabled: disabledReasons.join(' '),
95
94
  });
@@ -6,7 +6,7 @@ export declare function createNewProjectForLocalDev(projectConfig: ProjectConfig
6
6
  export declare function createInitialBuildForNewProject(projectConfig: ProjectConfig, projectDir: string, targetAccountId: number, sendIR?: boolean, profile?: string): Promise<Build>;
7
7
  export declare function compareLocalProjectToDeployed(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number | undefined, localProjectNodes: {
8
8
  [key: string]: IntermediateRepresentationNodeLocalDev;
9
- }, profile?: string): Promise<void>;
9
+ }): Promise<void>;
10
10
  export declare function isDeployedProjectUpToDateWithLocal(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number, localProjectNodes: {
11
11
  [key: string]: IntermediateRepresentationNodeLocalDev;
12
- }, profile?: string): Promise<boolean>;
12
+ }): Promise<boolean>;
@@ -123,7 +123,7 @@ export async function createInitialBuildForNewProject(projectConfig, projectDir,
123
123
  }
124
124
  return initialUploadResult.buildResult;
125
125
  }
126
- export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
126
+ export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes) {
127
127
  uiLogger.log('');
128
128
  if (!deployedBuildId) {
129
129
  uiLogger.error(lib.localDevHelpers.project.compareLocalProjectToDeployed.noDeployedBuild(projectConfig.name, uiAccountDescription(accountId)));
@@ -132,7 +132,7 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
132
132
  SpinniesManager.add('compareLocalProjectToDeployed', {
133
133
  text: lib.localDevHelpers.project.compareLocalProjectToDeployed.checking,
134
134
  });
135
- const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile);
135
+ const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes);
136
136
  if (isUpToDate) {
137
137
  SpinniesManager.succeed('compareLocalProjectToDeployed', {
138
138
  text: lib.localDevHelpers.project.compareLocalProjectToDeployed.upToDate,
@@ -144,11 +144,12 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
144
144
  .notUpToDate,
145
145
  });
146
146
  uiLogger.log('');
147
- uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed.notUpToDateExplanation(profile));
147
+ uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed
148
+ .notUpToDateExplanation);
148
149
  process.exit(EXIT_CODES.SUCCESS);
149
150
  }
150
151
  }
151
- export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
152
+ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes) {
152
153
  let tempDir = null;
153
154
  try {
154
155
  tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'hubspot-project-compare-'));
@@ -160,7 +161,7 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
160
161
  projectSourceDir: deployedProjectSourceDir,
161
162
  platformVersion: projectConfig.platformVersion,
162
163
  accountId: accountId,
163
- }, { profile });
164
+ }, {});
164
165
  return isDeepEqual(localProjectNodes, deployedProjectNodes, ['localDev']);
165
166
  }
166
167
  finally {
@@ -1,5 +1,5 @@
1
1
  import { ComponentTypes, Component, GenericComponentConfig, PublicAppComponentConfig, PrivateAppComponentConfig, AppCardComponentConfig } from '../../types/Projects.js';
2
- import { IntermediateRepresentationNode, IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types.js';
2
+ import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types.js';
3
3
  import { AppIRNode } from '../../types/ProjectComponents.js';
4
4
  export declare const CONFIG_FILES: {
5
5
  [k in ComponentTypes]: string;
@@ -15,4 +15,4 @@ export declare function getProjectComponentTypes(components: Array<Component>):
15
15
  export declare function getComponentUid(component?: Component | null): string | null;
16
16
  export declare function componentIsApp(component?: Component | null): component is Component<PublicAppComponentConfig | PrivateAppComponentConfig>;
17
17
  export declare function componentIsPublicApp(component?: Component | null): component is Component<PublicAppComponentConfig>;
18
- export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev | IntermediateRepresentationNode): component is AppIRNode;
18
+ export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev): component is AppIRNode;
@@ -1,5 +1,4 @@
1
1
  import { FileResult } from 'tmp';
2
- import { IntermediateRepresentation } from '@hubspot/project-parsing-lib';
3
2
  import { ProjectConfig } from '../../types/Projects.js';
4
3
  type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId: number) => Promise<T>;
5
4
  type ProjectUploadResult<T> = {
@@ -21,5 +20,5 @@ type HandleProjectUploadArg<T> = {
21
20
  export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
22
21
  export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig): void;
23
22
  export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
24
- export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<IntermediateRepresentation | undefined>;
23
+ export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<unknown>;
25
24
  export {};
@@ -133,5 +133,4 @@ export async function handleTranslate(projectDir, projectConfig, accountId, skip
133
133
  }
134
134
  throw e;
135
135
  }
136
- return undefined;
137
136
  }
@@ -7,10 +7,8 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
7
7
 
8
8
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
9
  **/
10
- import readline from 'readline';
11
10
  import chalk from 'chalk';
12
- import cliCursor from 'cli-cursor';
13
- import { breakText, cleanStream, colorOptions, getLinesLength, purgeSpinnerOptions, purgeSpinnersOptions, SPINNERS, terminalSupportsUnicode, writeStream, prefixOptions, } from './spinniesUtils.js';
11
+ import { colorOptions, purgeSpinnerOptions, purgeSpinnersOptions, SPINNERS, terminalSupportsUnicode, } from './spinniesUtils.js';
14
12
  function safeColor(text, color) {
15
13
  const chalkFn = chalk[color];
16
14
  if (typeof chalkFn === 'function') {
@@ -36,14 +34,10 @@ class SpinniesManager {
36
34
  succeedColor: 'green',
37
35
  failColor: 'red',
38
36
  spinner: terminalSupportsUnicode() ? SPINNERS.dots : SPINNERS.dashes,
39
- disableSpins: false,
37
+ disableSpins: true,
40
38
  ...purgeSpinnersOptions(options),
41
39
  };
42
- this.spin =
43
- !this.options.disableSpins &&
44
- !process.env.CI &&
45
- process.stderr &&
46
- process.stderr.isTTY;
40
+ this.spin = false;
47
41
  if (!this.hasAnySpinners()) {
48
42
  this.resetState();
49
43
  }
@@ -141,22 +135,7 @@ class SpinniesManager {
141
135
  status = status || 'spinning';
142
136
  this.spinners[name] = { ...this.spinners[name], ...options, status };
143
137
  }
144
- updateSpinnerState() {
145
- if (this.spin) {
146
- if (this.currentInterval) {
147
- clearInterval(this.currentInterval);
148
- }
149
- this.currentInterval = this.loopStream();
150
- if (!this.isCursorHidden) {
151
- cliCursor.hide();
152
- }
153
- this.isCursorHidden = true;
154
- this.checkIfActiveSpinners();
155
- }
156
- else {
157
- this.setRawStreamOutput();
158
- }
159
- }
138
+ updateSpinnerState() { }
160
139
  loopStream() {
161
140
  const frames = this.options.spinner?.frames || SPINNERS.dots.frames;
162
141
  const interval = this.options.spinner?.interval || SPINNERS.dots.interval;
@@ -168,86 +147,10 @@ class SpinniesManager {
168
147
  : ++this.currentFrameIndex;
169
148
  }, interval);
170
149
  }
171
- setStreamOutput(frame = '') {
172
- let output = '';
173
- const linesLength = [];
174
- const hasActiveSpinners = this.hasActiveSpinners();
175
- Object.values(this.spinners).forEach(spinner => {
176
- let { text } = spinner;
177
- const { status, color, spinnerColor, succeedColor, failColor, indent = 0, succeedPrefix = prefixOptions(this.options).succeedPrefix, failPrefix = prefixOptions(this.options).failPrefix, } = spinner;
178
- let line;
179
- let prefixLength = indent;
180
- text = text ?? '';
181
- if (status === 'spinning') {
182
- prefixLength += frame.length + 1;
183
- text = breakText(text, prefixLength);
184
- const colorizedFrame = safeColor(frame, spinnerColor);
185
- const colorizedText = safeColor(text, color);
186
- line = `${colorizedFrame} ${colorizedText}`;
187
- }
188
- else {
189
- if (status === 'succeed') {
190
- prefixLength += succeedPrefix.length + 1;
191
- if (hasActiveSpinners) {
192
- text = breakText(text, prefixLength);
193
- }
194
- const colorizedText = safeColor(text, succeedColor);
195
- line = `${chalk.green(succeedPrefix)} ${colorizedText}`;
196
- }
197
- else if (status === 'fail') {
198
- prefixLength += failPrefix.length + 1;
199
- if (hasActiveSpinners) {
200
- text = breakText(text, prefixLength);
201
- }
202
- const colorizedText = safeColor(text, failColor);
203
- line = `${chalk.red(failPrefix)} ${colorizedText}`;
204
- }
205
- else {
206
- if (hasActiveSpinners) {
207
- text = breakText(text, prefixLength);
208
- }
209
- line = safeColor(text, color);
210
- }
211
- }
212
- linesLength.push(...getLinesLength(text, prefixLength));
213
- output += indent ? `${' '.repeat(indent)}${line}\n` : `${line}\n`;
214
- });
215
- if (!hasActiveSpinners) {
216
- readline.clearScreenDown(this.stream);
217
- }
218
- writeStream(this.stream, output, linesLength);
219
- if (hasActiveSpinners) {
220
- cleanStream(this.stream, linesLength);
221
- }
222
- this.lineCount = linesLength.length;
223
- }
224
- setRawStreamOutput() {
225
- Object.values(this.spinners).forEach(i => {
226
- process.stderr.write(`- ${i.text}\n`);
227
- });
228
- }
229
- checkIfActiveSpinners() {
230
- if (!this.hasActiveSpinners()) {
231
- if (this.spin) {
232
- this.setStreamOutput();
233
- readline.moveCursor(this.stream, 0, this.lineCount);
234
- if (this.currentInterval) {
235
- clearInterval(this.currentInterval);
236
- }
237
- this.isCursorHidden = false;
238
- cliCursor.show();
239
- }
240
- this.spinners = {};
241
- }
242
- }
243
- bindSigint() {
244
- process.removeAllListeners('SIGINT');
245
- process.on('SIGINT', () => {
246
- cliCursor.show();
247
- readline.moveCursor(process.stderr, 0, this.lineCount);
248
- process.exit(0);
249
- });
250
- }
150
+ setStreamOutput(frame = '') { }
151
+ setRawStreamOutput() { }
152
+ checkIfActiveSpinners() { }
153
+ bindSigint() { }
251
154
  }
252
155
  const toExport = new SpinniesManager();
253
156
  export default toExport;
@@ -31,7 +31,7 @@ const inputSchema = {
31
31
  };
32
32
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
33
33
  const inputSchemaZodObject = z.object({ ...inputSchema });
34
- const toolName = 'create-cms-function';
34
+ const toolName = 'create-hubspot-cms-function';
35
35
  export class HsCreateFunctionTool extends Tool {
36
36
  constructor(mcpServer) {
37
37
  super(mcpServer);
@@ -47,7 +47,7 @@ const inputSchema = {
47
47
  };
48
48
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
49
49
  const inputSchemaZodObject = z.object({ ...inputSchema });
50
- const toolName = 'create-cms-module';
50
+ const toolName = 'create-hubspot-cms-module';
51
51
  export class HsCreateModuleTool extends Tool {
52
52
  constructor(mcpServer) {
53
53
  super(mcpServer);
@@ -23,7 +23,7 @@ const inputSchema = {
23
23
  };
24
24
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
25
  const inputSchemaZodObject = z.object({ ...inputSchema });
26
- const toolName = 'create-cms-template';
26
+ const toolName = 'create-hubspot-cms-template';
27
27
  export class HsCreateTemplateTool extends Tool {
28
28
  constructor(mcpServer) {
29
29
  super(mcpServer);
@@ -26,7 +26,7 @@ const inputSchema = {
26
26
  };
27
27
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
28
  const inputSchemaZodObject = z.object({ ...inputSchema });
29
- const toolName = 'get-cms-serverless-function-logs';
29
+ const toolName = 'get-hubspot-cms-serverless-function-logs';
30
30
  export class HsFunctionLogsTool extends Tool {
31
31
  constructor(mcpServer) {
32
32
  super(mcpServer);
@@ -69,7 +69,7 @@ export class HsFunctionLogsTool extends Tool {
69
69
  register() {
70
70
  return this.mcpServer.registerTool(toolName, {
71
71
  title: 'Get HubSpot CMS serverless function logs for an endpoint',
72
- description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-cms-serverless-functions to get the endpoint path.',
72
+ description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-hubspot-cms-serverless-functions to get the endpoint path.',
73
73
  inputSchema,
74
74
  }, this.handler);
75
75
  }
@@ -18,7 +18,7 @@ const inputSchema = {
18
18
  };
19
19
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
20
  const inputSchemaZodObject = z.object({ ...inputSchema });
21
- const toolName = 'list-cms-serverless-functions';
21
+ const toolName = 'list-hubspot-cms-serverless-functions';
22
22
  export class HsListFunctionsTool extends Tool {
23
23
  constructor(mcpServer) {
24
24
  super(mcpServer);
@@ -18,7 +18,7 @@ const inputSchema = {
18
18
  };
19
19
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
20
  const inputSchemaZodObject = z.object({ ...inputSchema });
21
- const toolName = 'list-cms-remote-contents';
21
+ const toolName = 'list-hubspot-cms-remote-contents';
22
22
  export class HsListTool extends Tool {
23
23
  constructor(mcpServer) {
24
24
  super(mcpServer);
@@ -28,7 +28,7 @@ describe('HsCreateFunctionTool', () => {
28
28
  describe('register', () => {
29
29
  it('should register the tool with the MCP server', () => {
30
30
  const result = tool.register();
31
- expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-function', {
31
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-hubspot-cms-function', {
32
32
  title: 'Create HubSpot CMS Serverless Function',
33
33
  description: `Creates a new HubSpot CMS serverless function using the hs create function command. Functions can be created non-interactively by specifying functionsFolder, filename, and endpointPath. Supports all HTTP methods (${HTTP_METHODS.join(', ')}).`,
34
34
  inputSchema: expect.any(Object),
@@ -27,7 +27,7 @@ describe('HsCreateModuleTool', () => {
27
27
  describe('register', () => {
28
28
  it('should register the tool with the MCP server', () => {
29
29
  const result = tool.register();
30
- expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-module', {
30
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-hubspot-cms-module', {
31
31
  title: 'Create HubSpot CMS Module',
32
32
  description: 'Creates a new HubSpot CMS module using the hs create module command. Modules can be created non-interactively by specifying moduleLabel and other module options. You can create either HubL or React modules by setting the reactType parameter.',
33
33
  inputSchema: expect.any(Object),
@@ -28,7 +28,7 @@ describe('HsCreateTemplateTool', () => {
28
28
  describe('register', () => {
29
29
  it('should register the tool with the MCP server', () => {
30
30
  const result = tool.register();
31
- expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-template', {
31
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-hubspot-cms-template', {
32
32
  title: 'Create HubSpot CMS Template',
33
33
  description: `Creates a new HubSpot CMS template using the hs create template command. Templates can be created non-interactively by specifying templateType. Supports all template types including: ${TEMPLATE_TYPES.join(', ')}.`,
34
34
  inputSchema: expect.any(Object),
@@ -27,9 +27,9 @@ describe('HsFunctionLogsTool', () => {
27
27
  describe('register', () => {
28
28
  it('should register the tool with the MCP server', () => {
29
29
  const result = tool.register();
30
- expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-cms-serverless-function-logs', expect.objectContaining({
30
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-hubspot-cms-serverless-function-logs', expect.objectContaining({
31
31
  title: 'Get HubSpot CMS serverless function logs for an endpoint',
32
- description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-cms-serverless-functions to get the endpoint path.',
32
+ description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-hubspot-cms-serverless-functions to get the endpoint path.',
33
33
  inputSchema: expect.any(Object),
34
34
  }), expect.any(Function));
35
35
  expect(result).toBe(mockRegisteredTool);
@@ -27,7 +27,7 @@ describe('HsListFunctionsTool', () => {
27
27
  describe('register', () => {
28
28
  it('should register the tool with the MCP server', () => {
29
29
  const result = tool.register();
30
- expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-cms-serverless-functions', {
30
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-hubspot-cms-serverless-functions', {
31
31
  title: 'List HubSpot CMS Serverless Functions',
32
32
  description: 'Get a list of all serverless functions deployed in a HubSpot portal/account. Shows function routes, HTTP methods, secrets, and timestamps.',
33
33
  inputSchema: expect.any(Object),
@@ -27,7 +27,7 @@ describe('HsListTool', () => {
27
27
  describe('register', () => {
28
28
  it('should register the tool with the MCP server', () => {
29
29
  const result = tool.register();
30
- expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-cms-remote-contents', {
30
+ expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-hubspot-cms-remote-contents', {
31
31
  title: 'List HubSpot CMS Directory Contents',
32
32
  description: 'List remote contents of a HubSpot CMS directory.',
33
33
  inputSchema: expect.any(Object),
@@ -6,19 +6,19 @@ declare const inputSchemaZodObject: z.ZodObject<{
6
6
  addApp: z.ZodBoolean;
7
7
  distribution: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"marketplace">, z.ZodLiteral<"private">]>>;
8
8
  auth: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"static">, z.ZodLiteral<"oauth">]>>;
9
- features: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"card">, z.ZodLiteral<"settings">, z.ZodLiteral<"app-function">, z.ZodLiteral<"webhooks">, z.ZodLiteral<"workflow-action">, z.ZodLiteral<"workflow-action-tool">, z.ZodLiteral<"app-object">, z.ZodLiteral<"app-event">, z.ZodLiteral<"scim">, z.ZodLiteral<"page">]>, "many">>;
9
+ features: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"card">, z.ZodLiteral<"settings">, z.ZodLiteral<"app-function">, z.ZodLiteral<"webhooks">, z.ZodLiteral<"workflow-action">, z.ZodLiteral<"workflow-action-tool">, z.ZodLiteral<"app-object">, z.ZodLiteral<"scim">]>, "many">>;
10
10
  }, "strip", z.ZodTypeAny, {
11
11
  absoluteProjectPath: string;
12
12
  addApp: boolean;
13
13
  auth?: "oauth" | "static" | undefined;
14
14
  distribution?: "marketplace" | "private" | undefined;
15
- features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
15
+ features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
16
16
  }, {
17
17
  absoluteProjectPath: string;
18
18
  addApp: boolean;
19
19
  auth?: "oauth" | "static" | undefined;
20
20
  distribution?: "marketplace" | "private" | undefined;
21
- features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
21
+ features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
22
22
  }>;
23
23
  export type AddFeatureInputSchema = z.infer<typeof inputSchemaZodObject>;
24
24
  export declare class AddFeatureToProjectTool extends Tool<AddFeatureInputSchema> {
@@ -16,20 +16,20 @@ const inputSchema = {
16
16
  z.literal(APP_DISTRIBUTION_TYPES.MARKETPLACE),
17
17
  z.literal(APP_DISTRIBUTION_TYPES.PRIVATE),
18
18
  ]))
19
- .describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Private is used if you do not wish to distribute your application on the HubSpot marketplace. '),
19
+ .describe('Private is used if you do not wish to distribute your application on the HubSpot marketplace. If not specified by the user, do not choose for them. This cannot be changed after a project is uploaded.'),
20
20
  auth: z
21
21
  .optional(z.union([
22
22
  z.literal(APP_AUTH_TYPES.STATIC),
23
23
  z.literal(APP_AUTH_TYPES.OAUTH),
24
24
  ]))
25
- .describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Static uses a static non changing authentication token, and is only available for private distribution. '),
25
+ .describe('Static uses a static non changing authentication token, and is only available for private distribution. If not specified by the user, do not choose for them. This cannot be changed after a project is uploaded.'),
26
26
  features,
27
27
  };
28
28
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
29
  const inputSchemaZodObject = z.object({
30
30
  ...inputSchema,
31
31
  });
32
- const toolName = 'add-feature-to-project';
32
+ const toolName = 'add-feature-to-hubspot-project';
33
33
  export class AddFeatureToProjectTool extends Tool {
34
34
  constructor(mcpServer) {
35
35
  super(mcpServer);
@@ -8,7 +8,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
8
8
  projectBase: z.ZodUnion<[z.ZodLiteral<"empty">, z.ZodLiteral<"app">]>;
9
9
  distribution: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"marketplace">, z.ZodLiteral<"private">]>>;
10
10
  auth: z.ZodOptional<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"static">, z.ZodLiteral<"oauth">]>>>;
11
- features: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"card">, z.ZodLiteral<"settings">, z.ZodLiteral<"app-function">, z.ZodLiteral<"webhooks">, z.ZodLiteral<"workflow-action">, z.ZodLiteral<"workflow-action-tool">, z.ZodLiteral<"app-object">, z.ZodLiteral<"app-event">, z.ZodLiteral<"scim">, z.ZodLiteral<"page">]>, "many">>;
11
+ features: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"card">, z.ZodLiteral<"settings">, z.ZodLiteral<"app-function">, z.ZodLiteral<"webhooks">, z.ZodLiteral<"workflow-action">, z.ZodLiteral<"workflow-action-tool">, z.ZodLiteral<"app-object">, z.ZodLiteral<"scim">]>, "many">>;
12
12
  }, "strip", z.ZodTypeAny, {
13
13
  projectBase: "app" | "empty";
14
14
  absoluteCurrentWorkingDirectory: string;
@@ -16,7 +16,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
16
16
  name?: string | undefined;
17
17
  auth?: "oauth" | "static" | undefined;
18
18
  distribution?: "marketplace" | "private" | undefined;
19
- features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
19
+ features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
20
20
  }, {
21
21
  projectBase: "app" | "empty";
22
22
  absoluteCurrentWorkingDirectory: string;
@@ -24,7 +24,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
24
24
  name?: string | undefined;
25
25
  auth?: "oauth" | "static" | undefined;
26
26
  distribution?: "marketplace" | "private" | undefined;
27
- features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
27
+ features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
28
28
  }>;
29
29
  export type CreateProjectInputSchema = z.infer<typeof inputSchemaZodObject>;
30
30
  export declare class CreateProjectTool extends Tool<CreateProjectInputSchema> {
@@ -10,11 +10,11 @@ const inputSchema = {
10
10
  absoluteCurrentWorkingDirectory,
11
11
  name: z
12
12
  .string()
13
- .describe('If not specified by the user, DO NOT choose for them. Changing this is potentially destructive.The name of the project to be created. This name is how your project will appear in HubSpot. ')
13
+ .describe('The name of the project to be created. This name is how your project will appear in HubSpot. If not specified by the user, do not choose for them. Changing this is potentially destructive.')
14
14
  .optional(),
15
15
  destination: z
16
16
  .string()
17
- .describe('DO NOT use the current directory unless the user has explicitly stated to do so. Relative path to the directory the project will be created in.'),
17
+ .describe('Relative path to the directory the project will be created in. DO NOT use the current directory unless the user has explicitly stated to do so.'),
18
18
  projectBase: z
19
19
  .union([z.literal(EMPTY_PROJECT), z.literal(PROJECT_WITH_APP)])
20
20
  .describe('Empty will create an empty project, and app will create a project with an app inside of it.'),
@@ -23,19 +23,19 @@ const inputSchema = {
23
23
  z.literal(APP_DISTRIBUTION_TYPES.MARKETPLACE),
24
24
  z.literal(APP_DISTRIBUTION_TYPES.PRIVATE),
25
25
  ]))
26
- .describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Private is used if you do not wish to distribute your application on the HubSpot marketplace. '),
26
+ .describe('Private is used if you do not wish to distribute your application on the HubSpot marketplace. If not specified by the user, do not choose for them. This cannot be changed after a project is uploaded.'),
27
27
  auth: z
28
28
  .optional(z.union([
29
29
  z.literal(APP_AUTH_TYPES.STATIC),
30
30
  z.literal(APP_AUTH_TYPES.OAUTH),
31
31
  ]))
32
- .describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Static uses a static non changing authentication token, and is only available for private distribution. ')
32
+ .describe('Static uses a static non changing authentication token, and is only available for private distribution. If not specified by the user, do not choose for them. This cannot be changed after a project is uploaded.')
33
33
  .optional(),
34
34
  features,
35
35
  };
36
36
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
37
37
  const inputSchemaZodObject = z.object({ ...inputSchema });
38
- const toolName = 'create-project';
38
+ const toolName = 'create-hubspot-project';
39
39
  export class CreateProjectTool extends Tool {
40
40
  constructor(mcpServer) {
41
41
  super(mcpServer);
@@ -15,7 +15,7 @@ const inputSchema = {
15
15
  const inputSchemaZodObject = z.object({
16
16
  ...inputSchema,
17
17
  });
18
- const toolName = 'deploy-project';
18
+ const toolName = 'deploy-hubspot-project';
19
19
  export class DeployProjectTool extends Tool {
20
20
  constructor(mcpServer) {
21
21
  super(mcpServer);
@@ -12,7 +12,7 @@ const inputSchema = {
12
12
  const inputSchemaZodObject = z.object({
13
13
  ...inputSchema,
14
14
  });
15
- const toolName = 'fetch-doc';
15
+ const toolName = 'fetch-hubspot-doc';
16
16
  export class DocFetchTool extends Tool {
17
17
  constructor(mcpServer) {
18
18
  super(mcpServer);
@@ -42,7 +42,7 @@ export class DocFetchTool extends Tool {
42
42
  register() {
43
43
  return this.mcpServer.registerTool(toolName, {
44
44
  title: 'Fetch HubSpot Developer Documentation (single file)',
45
- description: 'Always use this immediately after `search-docs` and before creating a plan, writing code, or answering technical questions. This tool retrieves the full, authoritative content of a HubSpot Developer Documentation page from its URL, ensuring responses are accurate, up-to-date, and grounded in the official docs.',
45
+ description: 'Always use this immediately after `search-hubspot-docs` and before creating a plan, writing code, or answering technical questions. This tool retrieves the full, authoritative content of a HubSpot Developer Documentation page from its URL, ensuring responses are accurate, up-to-date, and grounded in the official docs.',
46
46
  inputSchema,
47
47
  }, this.handler);
48
48
  }
@@ -13,7 +13,7 @@ const inputSchema = {
13
13
  const inputSchemaZodObject = z.object({
14
14
  ...inputSchema,
15
15
  });
16
- const toolName = 'search-docs';
16
+ const toolName = 'search-hubspot-docs';
17
17
  export class DocsSearchTool extends Tool {
18
18
  constructor(mcpServer) {
19
19
  super(mcpServer);
@@ -55,7 +55,7 @@ export class DocsSearchTool extends Tool {
55
55
  register() {
56
56
  return this.mcpServer.registerTool(toolName, {
57
57
  title: 'Search HubSpot Developer Documentation',
58
- description: 'Use this first whenever you need details about HubSpot APIs, SDKs, integrations, or developer platform features. This searches the official HubSpot Developer Documentation and returns the most relevant pages, each with a URL for use in `fetch-doc`. Always follow this with a fetch to get the full, authoritative content before making plans or writing answers.',
58
+ description: 'Use this first whenever you need details about HubSpot APIs, SDKs, integrations, or developer platform features. This searches the official HubSpot Developer Documentation and returns the most relevant pages, each with a URL for use in `fetch-hubspot-doc`. Always follow this with a fetch to get the full, authoritative content before making plans or writing answers.',
59
59
  inputSchema,
60
60
  }, this.handler);
61
61
  }