@hubspot/cli 7.8.1-experimental.0 → 7.8.3-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 (79) hide show
  1. package/commands/__tests__/getStarted.test.js +2 -2
  2. package/commands/__tests__/mcp.test.js +1 -1
  3. package/commands/__tests__/project.test.js +0 -3
  4. package/commands/app/__tests__/migrate.test.js +0 -1
  5. package/commands/app/migrate.js +4 -5
  6. package/commands/app/secret/add.js +2 -1
  7. package/commands/app/secret/delete.js +2 -1
  8. package/commands/app/secret/list.js +2 -1
  9. package/commands/app/secret/update.js +2 -1
  10. package/commands/app/secret.js +2 -1
  11. package/commands/app.js +2 -2
  12. package/commands/config/set.js +0 -1
  13. package/commands/feedback.js +1 -1
  14. package/commands/getStarted.d.ts +0 -2
  15. package/commands/getStarted.js +2 -2
  16. package/commands/mcp/__tests__/setup.test.js +2 -2
  17. package/commands/mcp/setup.js +3 -2
  18. package/commands/mcp.js +3 -3
  19. package/commands/project/__tests__/create.test.js +6 -6
  20. package/commands/project/__tests__/deploy.test.js +0 -3
  21. package/commands/project/__tests__/devUnifiedFlow.test.js +2 -4
  22. package/commands/project/__tests__/logs.test.js +0 -3
  23. package/commands/project/__tests__/migrate.test.js +1 -2
  24. package/commands/project/__tests__/migrateApp.test.js +1 -2
  25. package/commands/project/__tests__/profile.test.js +1 -1
  26. package/commands/project/add.js +1 -5
  27. package/commands/project/create.js +3 -9
  28. package/commands/project/deploy.js +2 -2
  29. package/commands/project/dev/index.js +4 -3
  30. package/commands/project/dev/unifiedFlow.js +5 -3
  31. package/commands/project/download.js +1 -2
  32. package/commands/project/installDeps.js +1 -2
  33. package/commands/project/listBuilds.js +2 -2
  34. package/commands/project/logs.js +2 -2
  35. package/commands/project/migrate.js +15 -6
  36. package/commands/project/migrateApp.js +1 -2
  37. package/commands/project/open.js +1 -2
  38. package/commands/project/profile/add.js +3 -3
  39. package/commands/project/profile/delete.js +1 -2
  40. package/commands/project/profile.js +2 -3
  41. package/commands/project/upload.js +2 -2
  42. package/commands/project/validate.js +1 -1
  43. package/commands/project/watch.js +2 -2
  44. package/commands/project.js +1 -2
  45. package/commands/sandbox/delete.js +1 -1
  46. package/commands/testAccount/importData.d.ts +1 -1
  47. package/commands/testAccount/importData.js +1 -1
  48. package/commands/testAccount.js +1 -1
  49. package/lang/en.d.ts +11 -3
  50. package/lang/en.js +13 -5
  51. package/lib/constants.d.ts +5 -0
  52. package/lib/constants.js +5 -0
  53. package/lib/mcp/setup.js +1 -1
  54. package/lib/middleware/fireAlarmMiddleware.js +15 -5
  55. package/lib/projects/__tests__/LocalDevProcess.test.js +227 -16
  56. package/lib/projects/__tests__/LocalDevWebsocketServer.test.js +16 -21
  57. package/lib/projects/__tests__/deploy.test.js +71 -6
  58. package/lib/projects/__tests__/localDevProjectHelpers.test.js +4 -2
  59. package/lib/projects/create/__tests__/v3.test.js +79 -4
  60. package/lib/projects/create/v3.js +8 -6
  61. package/lib/projects/localDev/AppDevModeInterface.js +5 -5
  62. package/lib/projects/localDev/LocalDevLogger.d.ts +4 -0
  63. package/lib/projects/localDev/LocalDevLogger.js +22 -0
  64. package/lib/projects/localDev/LocalDevProcess.d.ts +7 -5
  65. package/lib/projects/localDev/LocalDevProcess.js +90 -19
  66. package/lib/projects/localDev/LocalDevState.d.ts +9 -8
  67. package/lib/projects/localDev/LocalDevState.js +18 -17
  68. package/lib/projects/localDev/LocalDevWebsocketServer.d.ts +2 -0
  69. package/lib/projects/localDev/LocalDevWebsocketServer.js +55 -23
  70. package/lib/projects/localDev/helpers/project.js +5 -1
  71. package/lib/projects/localDev/localDevWebsocketServerUtils.d.ts +4 -0
  72. package/lib/projects/localDev/localDevWebsocketServerUtils.js +10 -0
  73. package/lib/projects/pollProjectBuildAndDeploy.js +4 -4
  74. package/lib/prompts/projectAddPrompt.js +2 -1
  75. package/lib/prompts/promptUtils.js +3 -0
  76. package/lib/prompts/selectProjectTemplatePrompt.js +2 -0
  77. package/package.json +4 -4
  78. package/types/LocalDev.d.ts +19 -3
  79. package/ui/index.js +1 -1
@@ -8,12 +8,14 @@ import { uiCommandReference } from '../../lib/ui/index.js';
8
8
  import { commands, lib } from '../../lang/en.js';
9
9
  import { uiLogger } from '../../lib/ui/logger.js';
10
10
  import { logInBox } from '../../lib/ui/boxen.js';
11
+ import { renderInline } from '../../ui/index.js';
12
+ import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
11
13
  import { getHasMigratableThemes, migrateThemes2025_2, } from '../../lib/theme/migrate.js';
12
14
  import { hasFeature } from '../../lib/hasFeature.js';
13
15
  import { FEATURES } from '../../lib/constants.js';
14
16
  const { v2025_2 } = PLATFORM_VERSIONS;
15
17
  const command = 'migrate';
16
- const describe = undefined; // commands.project.migrate.describe
18
+ const describe = commands.project.migrate.describe;
17
19
  async function handler(args) {
18
20
  const { platformVersion, unstable } = args;
19
21
  const projectConfig = await getProjectConfig();
@@ -22,10 +24,18 @@ async function handler(args) {
22
24
  return process.exit(EXIT_CODES.ERROR);
23
25
  }
24
26
  if (projectConfig?.projectConfig) {
25
- await logInBox({
26
- contents: lib.migrate.projectMigrationWarning,
27
- options: { title: lib.migrate.projectMigrationWarningTitle },
28
- });
27
+ if (!process.env.HUBSPOT_ENABLE_INK) {
28
+ await logInBox({
29
+ contents: lib.migrate.projectMigrationWarning,
30
+ options: { title: lib.migrate.projectMigrationWarningTitle },
31
+ });
32
+ }
33
+ else {
34
+ await renderInline(getWarningBox({
35
+ title: lib.migrate.projectMigrationWarningTitle,
36
+ message: lib.migrate.projectMigrationWarning,
37
+ }));
38
+ }
29
39
  }
30
40
  const { derivedAccountId } = args;
31
41
  try {
@@ -65,7 +75,6 @@ function projectMigrateBuilder(yargs) {
65
75
  type: 'string',
66
76
  choices: [v2025_2],
67
77
  default: v2025_2,
68
- hidden: true,
69
78
  })
70
79
  .option('unstable', {
71
80
  type: 'boolean',
@@ -34,8 +34,7 @@ function projectMigrateAppBuilder(yargs) {
34
34
  'platform-version': {
35
35
  type: 'string',
36
36
  choices: [v2023_2, v2025_2],
37
- hidden: true,
38
- default: v2023_2,
37
+ default: v2025_2,
39
38
  },
40
39
  });
41
40
  yargs.example([
@@ -6,11 +6,10 @@ import { getProjectConfig } from '../../lib/projects/config.js';
6
6
  import { ensureProjectExists } from '../../lib/projects/ensureProjectExists.js';
7
7
  import { getProjectDetailUrl } from '../../lib/projects/urls.js';
8
8
  import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
9
- import { uiBetaTag } from '../../lib/ui/index.js';
10
9
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
11
10
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
12
11
  const command = 'open';
13
- const describe = uiBetaTag(i18n(`commands.project.subcommands.open.describe`), false);
12
+ const describe = i18n(`commands.project.subcommands.open.describe`);
14
13
  async function handler(args) {
15
14
  const { project, derivedAccountId } = args;
16
15
  trackCommandUsage('project-open', undefined, derivedAccountId);
@@ -5,7 +5,7 @@ import { getAccountIdentifier } from '@hubspot/local-dev-lib/config/getAccountId
5
5
  import { getAllHsProfiles, getHsProfileFilename, loadHsProfileFile, } from '@hubspot/project-parsing-lib';
6
6
  import { trackCommandUsage } from '../../../lib/usageTracking.js';
7
7
  import { getProjectConfig } from '../../../lib/projects/config.js';
8
- import { uiBetaTag, uiAccountDescription } from '../../../lib/ui/index.js';
8
+ import { uiAccountDescription } from '../../../lib/ui/index.js';
9
9
  import { uiLogger } from '../../../lib/ui/logger.js';
10
10
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
11
11
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
@@ -14,8 +14,8 @@ import { promptUser, listPrompt, confirmPrompt, } from '../../../lib/prompts/pro
14
14
  import { fileExists } from '../../../lib/validation.js';
15
15
  import { debugError } from '../../../lib/errorHandlers/index.js';
16
16
  const command = 'add [name]';
17
- const describe = uiBetaTag(commands.project.profile.add.describe, false);
18
- const verboseDescribe = uiBetaTag(commands.project.profile.add.verboseDescribe, false);
17
+ const describe = commands.project.profile.add.describe;
18
+ const verboseDescribe = commands.project.profile.add.verboseDescribe;
19
19
  async function selectProfileToCopyVariablesFrom(existingProfiles) {
20
20
  let profileToCopyVariablesFrom;
21
21
  if (existingProfiles.length == 1) {
@@ -5,7 +5,6 @@ import { fetchProject, deleteProject, } from '@hubspot/local-dev-lib/api/project
5
5
  import { getAccountConfig } from '@hubspot/local-dev-lib/config';
6
6
  import { trackCommandUsage } from '../../../lib/usageTracking.js';
7
7
  import { getProjectConfig } from '../../../lib/projects/config.js';
8
- import { uiBetaTag } from '../../../lib/ui/index.js';
9
8
  import { uiLogger } from '../../../lib/ui/logger.js';
10
9
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
11
10
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
@@ -15,7 +14,7 @@ import { fileExists } from '../../../lib/validation.js';
15
14
  import { debugError } from '../../../lib/errorHandlers/index.js';
16
15
  import { isDeveloperTestAccount, isSandbox, } from '../../../lib/accountTypes.js';
17
16
  const command = 'delete [name]';
18
- const describe = uiBetaTag(commands.project.profile.delete.describe, false);
17
+ const describe = commands.project.profile.delete.describe;
19
18
  async function handler(args) {
20
19
  const { derivedAccountId } = args;
21
20
  trackCommandUsage('project-profile-delete', undefined, derivedAccountId);
@@ -1,11 +1,10 @@
1
- import { uiBetaTag } from '../../lib/ui/index.js';
2
1
  import add from './profile/add.js';
3
2
  import deleteProfile from './profile/delete.js';
4
3
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
5
4
  import { commands } from '../../lang/en.js';
6
5
  const command = ['profile', 'profiles'];
7
- const describe = undefined; // uiBetaTag(commands.project.profile.describe, false);
8
- const verboseDescribe = uiBetaTag(commands.project.profile.verboseDescribe, false);
6
+ const describe = commands.project.profile.describe;
7
+ const verboseDescribe = commands.project.profile.verboseDescribe;
9
8
  function projectProfileBuilder(yargs) {
10
9
  yargs.command(add).command(deleteProfile).demandCommand(1, '');
11
10
  return yargs;
@@ -3,7 +3,7 @@ import { logger } from '@hubspot/local-dev-lib/logger';
3
3
  import { getAccountConfig } from '@hubspot/local-dev-lib/config';
4
4
  import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
5
5
  import { useV3Api } from '../../lib/projects/platformVersion.js';
6
- import { uiBetaTag, uiCommandReference } from '../../lib/ui/index.js';
6
+ import { uiCommandReference } from '../../lib/ui/index.js';
7
7
  import { trackCommandUsage } from '../../lib/usageTracking.js';
8
8
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
9
9
  import { logFeedbackMessage } from '../../lib/projects/ui.js';
@@ -17,7 +17,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
17
17
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
18
18
  import { uiLogger } from '../../lib/ui/logger.js';
19
19
  const command = 'upload';
20
- const describe = uiBetaTag(i18n(`commands.project.subcommands.upload.describe`), false);
20
+ const describe = i18n(`commands.project.subcommands.upload.describe`);
21
21
  async function handler(args) {
22
22
  const { forceCreate, message, derivedAccountId, skipValidation, formatOutputAsJson, profile, } = args;
23
23
  const jsonOutput = {};
@@ -11,7 +11,7 @@ import { commands } from '../../lang/en.js';
11
11
  import { loadAndValidateProfile } from '../../lib/projectProfiles.js';
12
12
  import { logError } from '../../lib/errorHandlers/index.js';
13
13
  const command = 'validate';
14
- const describe = undefined;
14
+ const describe = commands.project.validate.describe;
15
15
  async function handler(args) {
16
16
  const { derivedAccountId, profile } = args;
17
17
  const { projectConfig, projectDir } = await getProjectConfig();
@@ -1,7 +1,7 @@
1
1
  import { cancelStagedBuild, fetchProjectBuilds, } from '@hubspot/local-dev-lib/api/projects';
2
2
  import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
3
3
  import { useV3Api } from '../../lib/projects/platformVersion.js';
4
- import { uiCommandReference, uiLink, uiBetaTag } from '../../lib/ui/index.js';
4
+ import { uiCommandReference, uiLink } from '../../lib/ui/index.js';
5
5
  import { i18n } from '../../lib/lang.js';
6
6
  import { createWatcher } from '../../lib/projects/watch.js';
7
7
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
@@ -16,7 +16,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
16
16
  import { handleKeypress, handleExit } from '../../lib/process.js';
17
17
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
18
18
  const command = 'watch';
19
- const describe = uiBetaTag(i18n(`commands.project.subcommands.watch.describe`), false);
19
+ const describe = i18n(`commands.project.subcommands.watch.describe`);
20
20
  async function handleBuildStatus(accountId, projectName, buildId) {
21
21
  const { isAutoDeployEnabled, deployStatusTaskLocator } = await pollBuildStatus(accountId, projectName, buildId, null);
22
22
  if (isAutoDeployEnabled && deployStatusTaskLocator) {
@@ -1,5 +1,4 @@
1
1
  import { i18n } from '../lib/lang.js';
2
- import { uiBetaTag } from '../lib/ui/index.js';
3
2
  import deploy from './project/deploy.js';
4
3
  import create from './project/create.js';
5
4
  import upload from './project/upload.js';
@@ -18,7 +17,7 @@ import profile from './project/profile.js';
18
17
  import projectValidate from './project/validate.js';
19
18
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
20
19
  const command = ['project', 'projects'];
21
- const describe = uiBetaTag(i18n(`commands.project.describe`), false);
20
+ const describe = i18n(`commands.project.describe`);
22
21
  function projectBuilder(yargs) {
23
22
  yargs
24
23
  .command(create)
@@ -121,7 +121,7 @@ async function handler(args) {
121
121
  const newDefaultAccount = await selectAccountFromConfig();
122
122
  updateDefaultAccount(newDefaultAccount);
123
123
  }
124
- else {
124
+ else if (isDefaultAccount && force) {
125
125
  // If force is specified, skip prompt and set the parent account id as the default account
126
126
  updateDefaultAccount(parentAccountId);
127
127
  }
@@ -1,6 +1,6 @@
1
1
  import { AccountArgs, CommonArgs, ConfigArgs, EnvironmentArgs, YargsCommandModule } from '../../types/Yargs.js';
2
2
  export declare const command = "import-data";
3
- export declare const describe: undefined;
3
+ export declare const describe: "Import data into the CRM";
4
4
  type CrmImportDataArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & {
5
5
  filePath: string | undefined;
6
6
  skipConfirm: boolean | undefined;
@@ -8,7 +8,7 @@ import { handleImportData, handleTargetTestAccountSelectionFlow, } from '../../l
8
8
  import { confirmImportDataPrompt } from '../../lib/prompts/confirmImportDataPrompt.js';
9
9
  import { commands } from '../../lang/en.js';
10
10
  export const command = 'import-data';
11
- export const describe = undefined; // commands.testAccount.subcommands.importData.describe;
11
+ export const describe = commands.testAccount.subcommands.importData.describe;
12
12
  async function handler(args) {
13
13
  const { derivedAccountId, userProvidedAccount, filePath: providedFilePath, skipConfirm, } = args;
14
14
  trackCommandUsage('crm-import-data', {}, derivedAccountId);
@@ -5,7 +5,7 @@ import deleteTestAccountCommand from './testAccount/delete.js';
5
5
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
6
6
  import { commands } from '../lang/en.js';
7
7
  const command = ['test-account', 'test-accounts'];
8
- const describe = undefined; //commands.testAccount.describe;
8
+ const describe = commands.testAccount.describe;
9
9
  function testAccountBuilder(yargs) {
10
10
  yargs
11
11
  .command(createTestAccountCommand)
package/lang/en.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare const commands: {
10
10
  };
11
11
  };
12
12
  readonly getStarted: {
13
+ readonly describe: "A step-by-step command to get you started with a HubSpot project.";
13
14
  readonly options: {
14
15
  readonly dest: {
15
16
  readonly describe: "Directory where the project should be created";
@@ -859,8 +860,9 @@ Global configuration replaces hubspot.config.yml, and you will be prompted to mi
859
860
  readonly tailLogs: (functionPath: string, accountId: string) => string;
860
861
  };
861
862
  readonly mcp: {
862
- readonly describe: "Commands for managing HubSpot MCP servers";
863
+ readonly describe: "Commands for managing HubSpot MCP servers.";
863
864
  readonly setup: {
865
+ readonly describe: "Setup the HubSpot development MCP servers.";
864
866
  readonly installingDocSearch: "Adding the docs-search mcp server";
865
867
  readonly claudeCode: "Claude Code";
866
868
  readonly cursor: "Cursor";
@@ -1009,7 +1011,7 @@ Profiles enable you to reference variables in your component configuration files
1009
1011
  readonly dev: {
1010
1012
  readonly describe: "Start local dev for the current project.";
1011
1013
  readonly logs: {
1012
- readonly betaMessage: "HubSpot projects local development";
1014
+ readonly header: "HubSpot projects local development";
1013
1015
  readonly placeholderAccountSelection: "Using default account as target account (for now)";
1014
1016
  readonly accountTypeInformation: "Testing in a developer test account is strongly recommended, but you can use a sandbox account if your plan allows you to create one.";
1015
1017
  readonly learnMoreMessageV3: `Learn more about ${string} | ${string}`;
@@ -1071,7 +1073,7 @@ ${string}`;
1071
1073
  readonly describe: "Project name (cannot be changed)";
1072
1074
  };
1073
1075
  readonly template: {
1074
- readonly describe: "The starting template";
1076
+ readonly describe: "The starting template. Only applies when platform version is less than 2025.2.";
1075
1077
  };
1076
1078
  readonly templateSource: {
1077
1079
  readonly describe: "Path to custom GitHub repository from which to create project template";
@@ -2593,8 +2595,13 @@ export declare const lib: {
2593
2595
  readonly LocalDevProcess: {
2594
2596
  readonly projectConfigMismatch: `Unable to upload project. The project config has been modified since starting ${string}.`;
2595
2597
  readonly uploadInitiated: "Project upload initiated from Local Dev UI.";
2598
+ readonly deployInitiated: "Project deploy initiated from Local Dev UI.";
2596
2599
  readonly uploadFailed: "Project upload failed. To proceed with local development, fix any necessary errors, then re-upload your project.";
2600
+ readonly deployFailed: "Project deploy failed. To proceed with local development, fix any necessary errors, then re-deploy your project.";
2597
2601
  readonly uploadSuccess: "Project upload completed successfully. Resuming local dev...";
2602
+ readonly uploadSuccessAutoDeployDisabled: "Project upload completed successfully, but auto-deploy is disabled for this project. Deploy your latest build to proceed with local development.";
2603
+ readonly deploySuccess: "Project deploy completed successfully. Resuming local dev...";
2604
+ readonly noBuildToDeploy: "Error deploying project. No build was found to deploy.";
2598
2605
  };
2599
2606
  readonly localDevHelpers: {
2600
2607
  readonly project: {
@@ -3113,6 +3120,7 @@ Run ${string} to upgrade to version ${string}`;
3113
3120
  };
3114
3121
  readonly projectAddPrompt: {
3115
3122
  readonly selectType: "[--type] Select an app feature to add: ";
3123
+ readonly selectFeatures: "[--features] Select an app feature to add: ";
3116
3124
  readonly enterName: "[--name] Give your component a name: ";
3117
3125
  readonly errors: {
3118
3126
  readonly nameRequired: "A component name is required";
package/lang/en.js CHANGED
@@ -19,6 +19,7 @@ export const commands = {
19
19
  },
20
20
  },
21
21
  getStarted: {
22
+ describe: 'A step-by-step command to get you started with a HubSpot project.',
22
23
  options: {
23
24
  dest: {
24
25
  describe: 'Directory where the project should be created',
@@ -863,8 +864,9 @@ export const commands = {
863
864
  tailLogs: (functionPath, accountId) => `Waiting for log entries for "${functionPath}" on account "${accountId}".\n`,
864
865
  },
865
866
  mcp: {
866
- describe: 'Commands for managing HubSpot MCP servers',
867
+ describe: 'Commands for managing HubSpot MCP servers.',
867
868
  setup: {
869
+ describe: 'Setup the HubSpot development MCP servers.',
868
870
  installingDocSearch: 'Adding the docs-search mcp server',
869
871
  claudeCode: 'Claude Code',
870
872
  cursor: 'Cursor',
@@ -1011,10 +1013,10 @@ export const commands = {
1011
1013
  dev: {
1012
1014
  describe: 'Start local dev for the current project.',
1013
1015
  logs: {
1014
- betaMessage: 'HubSpot projects local development',
1016
+ header: 'HubSpot projects local development',
1015
1017
  placeholderAccountSelection: 'Using default account as target account (for now)',
1016
1018
  accountTypeInformation: 'Testing in a developer test account is strongly recommended, but you can use a sandbox account if your plan allows you to create one.',
1017
- learnMoreMessageV3: `Learn more about ${uiLink('HubSpot projects local dev', 'https://hubspot.mintlify.io/en-us/developer-tooling/local-development/hubspot-cli/project-commands#start-a-local-development-server')} | ${uiLink('HubSpot account types', 'https://developers.hubspot.com/docs/getting-started/account-types')}`,
1019
+ learnMoreMessageV3: `Learn more about ${uiLink('HubSpot projects local dev', 'https://developers.hubspot.com/docs/developer-tooling/local-development/hubspot-cli/project-commands#start-a-local-development-server')} | ${uiLink('HubSpot account types', 'https://developers.hubspot.com/docs/getting-started/account-types')}`,
1018
1020
  learnMoreMessageLegacy: uiLink('Learn more about the projects local dev server', 'https://developers.hubspot.com/docs/platform/project-cli-commands#start-a-local-development-server'),
1019
1021
  profileProjectAccountExplanation: (accountId, profileName) => `Using account ${uiAccountDescription(accountId)} from profile ${chalk.bold(profileName)} for project upload`,
1020
1022
  defaultProjectAccountExplanation: (accountId) => `Using default account ${uiAccountDescription(accountId)} for project upload`,
@@ -1071,7 +1073,7 @@ export const commands = {
1071
1073
  describe: 'Project name (cannot be changed)',
1072
1074
  },
1073
1075
  template: {
1074
- describe: 'The starting template',
1076
+ describe: 'The starting template. Only applies when platform version is less than 2025.2.',
1075
1077
  },
1076
1078
  templateSource: {
1077
1079
  describe: 'Path to custom GitHub repository from which to create project template',
@@ -1195,7 +1197,7 @@ export const commands = {
1195
1197
  maxExceeded: (maxCount) => `This project has the maximum allowed(${maxCount})`,
1196
1198
  authTypeNotAllowed: (authType) => `Auth type '${authType}' not allowed.`,
1197
1199
  distributionNotAllowed: (dist) => `Distribution '${dist}' not allowed.`,
1198
- portalDoesNotHaveAccessToThisFeature: (accountId) => `The account ${uiAccountDescription(accountId)} does not have access to this feature`,
1200
+ portalDoesNotHaveAccessToThisFeature: (accountId) => `The account ${uiAccountDescription(accountId)} does not have access to this feature.`,
1199
1201
  locationInProject: 'This command must be run from within a project directory.',
1200
1202
  failedToFetchComponentList: 'Failed to fetch the list of available features. Please try again later.',
1201
1203
  projectContainsPublicApp: 'This project contains a public app. This command is currently only compatible with projects that contain private apps.',
@@ -2591,8 +2593,13 @@ export const lib = {
2591
2593
  LocalDevProcess: {
2592
2594
  projectConfigMismatch: `Unable to upload project. The project config has been modified since starting ${uiCommandReference('hs project dev')}.`,
2593
2595
  uploadInitiated: 'Project upload initiated from Local Dev UI.',
2596
+ deployInitiated: 'Project deploy initiated from Local Dev UI.',
2594
2597
  uploadFailed: 'Project upload failed. To proceed with local development, fix any necessary errors, then re-upload your project.',
2598
+ deployFailed: 'Project deploy failed. To proceed with local development, fix any necessary errors, then re-deploy your project.',
2595
2599
  uploadSuccess: 'Project upload completed successfully. Resuming local dev...',
2600
+ uploadSuccessAutoDeployDisabled: 'Project upload completed successfully, but auto-deploy is disabled for this project. Deploy your latest build to proceed with local development.',
2601
+ deploySuccess: 'Project deploy completed successfully. Resuming local dev...',
2602
+ noBuildToDeploy: 'Error deploying project. No build was found to deploy.',
2596
2603
  },
2597
2604
  localDevHelpers: {
2598
2605
  project: {
@@ -3108,6 +3115,7 @@ export const lib = {
3108
3115
  },
3109
3116
  projectAddPrompt: {
3110
3117
  selectType: '[--type] Select an app feature to add: ',
3118
+ selectFeatures: '[--features] Select an app feature to add: ',
3111
3119
  enterName: '[--name] Give your component a name: ',
3112
3120
  errors: {
3113
3121
  nameRequired: 'A component name is required',
@@ -84,17 +84,22 @@ export declare const FEATURES: {
84
84
  readonly APPS_HOME: "UIE:AppHome";
85
85
  readonly MCP_ACCESS: "Developers:CLIMCPAccess";
86
86
  readonly THEME_MIGRATION_2025_2: "Developers:ProjectThemeMigrations:2025.2";
87
+ readonly AGENT_TOOLS: "ThirdPartyAgentTools";
87
88
  };
88
89
  export declare const LOCAL_DEV_UI_MESSAGE_SEND_TYPES: {
89
90
  UPLOAD_SUCCESS: string;
90
91
  UPLOAD_FAILURE: string;
92
+ DEPLOY_SUCCESS: string;
93
+ DEPLOY_FAILURE: string;
91
94
  UPDATE_PROJECT_NODES: string;
92
95
  UPDATE_APP_DATA: string;
93
96
  UPDATE_PROJECT_DATA: string;
94
97
  UPDATE_UPLOAD_WARNINGS: string;
98
+ CLI_METADATA: string;
95
99
  };
96
100
  export declare const LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES: {
97
101
  UPLOAD: string;
102
+ DEPLOY: string;
98
103
  VIEWED_WELCOME_SCREEN: string;
99
104
  };
100
105
  export declare const APP_INSTALLATION_STATES: {
package/lib/constants.js CHANGED
@@ -76,17 +76,22 @@ export const FEATURES = {
76
76
  APPS_HOME: 'UIE:AppHome',
77
77
  MCP_ACCESS: 'Developers:CLIMCPAccess',
78
78
  THEME_MIGRATION_2025_2: 'Developers:ProjectThemeMigrations:2025.2',
79
+ AGENT_TOOLS: 'ThirdPartyAgentTools',
79
80
  };
80
81
  export const LOCAL_DEV_UI_MESSAGE_SEND_TYPES = {
81
82
  UPLOAD_SUCCESS: 'server:uploadSuccess',
82
83
  UPLOAD_FAILURE: 'server:uploadFailure',
84
+ DEPLOY_SUCCESS: 'server:deploySuccess',
85
+ DEPLOY_FAILURE: 'server:deployFailure',
83
86
  UPDATE_PROJECT_NODES: 'server:updateProjectNodes',
84
87
  UPDATE_APP_DATA: 'server:updateAppData',
85
88
  UPDATE_PROJECT_DATA: 'server:updateProjectData',
86
89
  UPDATE_UPLOAD_WARNINGS: 'server:updateUploadWarnings',
90
+ CLI_METADATA: 'server:cliMetadata',
87
91
  };
88
92
  export const LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES = {
89
93
  UPLOAD: 'client:upload',
94
+ DEPLOY: 'client:deploy',
90
95
  VIEWED_WELCOME_SCREEN: 'client:viewedWelcomeScreen',
91
96
  };
92
97
  export const APP_INSTALLATION_STATES = {
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 = 'HubSpotDev';
12
12
  const claudeCode = 'claude';
13
13
  const windsurf = 'windsurf';
14
14
  const cursor = 'cursor';
@@ -3,6 +3,8 @@ import { fetchFireAlarms } from '@hubspot/local-dev-lib/api/fireAlarm';
3
3
  import { debugError } from '../errorHandlers/index.js';
4
4
  import pkg from '../../package.json' with { type: 'json' };
5
5
  import { logInBox } from '../ui/boxen.js';
6
+ import { renderInline } from '../../ui/index.js';
7
+ import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
6
8
  /*
7
9
  * Versions can be formatted like this:
8
10
  * =7.2.2 -> targets the exact version 7.2.2
@@ -98,12 +100,20 @@ async function logFireAlarms(accountId, command, version) {
98
100
  }
99
101
  return acc;
100
102
  }, '');
101
- await logInBox({
102
- contents: notifications,
103
- options: {
103
+ if (!process.env.HUBSPOT_ENABLE_INK) {
104
+ await logInBox({
105
+ contents: notifications,
106
+ options: {
107
+ title: 'Notifications',
108
+ },
109
+ });
110
+ }
111
+ else {
112
+ await renderInline(getWarningBox({
104
113
  title: 'Notifications',
105
- },
106
- });
114
+ message: notifications,
115
+ }));
116
+ }
107
117
  }
108
118
  }
109
119
  export async function checkFireAlarms(argv) {