@hubspot/cli 7.6.0-beta.10 → 7.6.0-beta.12

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 (150) hide show
  1. package/commands/app/__tests__/migrate.test.js +1 -0
  2. package/commands/getStarted.js +70 -22
  3. package/commands/mcp/setup.d.ts +0 -1
  4. package/commands/mcp/setup.js +3 -11
  5. package/commands/project/__tests__/add.test.js +64 -0
  6. package/commands/project/__tests__/create.test.js +57 -0
  7. package/commands/project/__tests__/deploy.test.js +3 -2
  8. package/commands/project/__tests__/devUnifiedFlow.test.js +14 -5
  9. package/commands/project/add.d.ts +1 -1
  10. package/commands/project/add.js +3 -5
  11. package/commands/project/create.js +7 -2
  12. package/commands/project/deploy.js +9 -61
  13. package/commands/project/dev/index.js +33 -13
  14. package/commands/project/dev/unifiedFlow.js +8 -7
  15. package/commands/project/upload.js +2 -2
  16. package/commands/project/validate.js +1 -1
  17. package/commands/project/watch.js +2 -2
  18. package/lang/en.d.ts +36 -13
  19. package/lang/en.js +49 -25
  20. package/lang/en.lyaml +12 -12
  21. package/lib/__tests__/hasFeature.test.js +145 -7
  22. package/lib/__tests__/importData.test.js +1 -1
  23. package/lib/app/migrate.js +9 -2
  24. package/lib/constants.d.ts +2 -0
  25. package/lib/constants.js +2 -0
  26. package/lib/errorHandlers/index.d.ts +4 -0
  27. package/lib/errorHandlers/index.js +1 -1
  28. package/lib/hasFeature.js +6 -0
  29. package/lib/importData.js +1 -1
  30. package/lib/mcp/setup.d.ts +0 -2
  31. package/lib/mcp/setup.js +4 -29
  32. package/lib/projects/__tests__/AppDevModeInterface.test.js +72 -44
  33. package/lib/projects/__tests__/LocalDevProcess.test.js +1 -0
  34. package/lib/projects/__tests__/components.test.js +164 -7
  35. package/lib/projects/__tests__/deploy.test.js +164 -0
  36. package/lib/projects/__tests__/platformVersion.test.d.ts +1 -0
  37. package/lib/projects/__tests__/{buildAndDeploy.test.js → platformVersion.test.js} +2 -2
  38. package/lib/projects/add/__tests__/legacyAddComponent.test.js +49 -6
  39. package/lib/projects/add/__tests__/v3AddComponent.test.js +142 -8
  40. package/lib/projects/add/legacyAddComponent.d.ts +1 -1
  41. package/lib/projects/add/legacyAddComponent.js +5 -1
  42. package/lib/projects/add/v3AddComponent.d.ts +2 -1
  43. package/lib/projects/add/v3AddComponent.js +22 -5
  44. package/lib/projects/components.d.ts +1 -0
  45. package/lib/projects/components.js +27 -1
  46. package/lib/projects/create/__tests__/v3.test.js +97 -9
  47. package/lib/projects/create/index.js +2 -2
  48. package/lib/projects/create/legacy.js +1 -1
  49. package/lib/projects/create/v3.d.ts +2 -2
  50. package/lib/projects/create/v3.js +35 -12
  51. package/lib/projects/deploy.d.ts +13 -0
  52. package/lib/projects/deploy.js +63 -0
  53. package/lib/projects/localDev/AppDevModeInterface.d.ts +5 -3
  54. package/lib/projects/localDev/AppDevModeInterface.js +132 -48
  55. package/lib/projects/localDev/DevServerManagerV2.js +1 -0
  56. package/lib/projects/localDev/LocalDevProcess.js +3 -1
  57. package/lib/projects/localDev/LocalDevState.d.ts +5 -2
  58. package/lib/projects/localDev/LocalDevState.js +9 -1
  59. package/lib/projects/localDev/helpers/account.js +2 -2
  60. package/lib/projects/localDev/helpers/project.d.ts +2 -2
  61. package/lib/projects/localDev/helpers/project.js +6 -8
  62. package/lib/projects/platformVersion.d.ts +1 -0
  63. package/lib/projects/platformVersion.js +10 -0
  64. package/lib/projects/{buildAndDeploy.d.ts → pollProjectBuildAndDeploy.d.ts} +0 -1
  65. package/lib/projects/{buildAndDeploy.js → pollProjectBuildAndDeploy.js} +0 -10
  66. package/lib/projects/upload.js +1 -1
  67. package/lib/projects/urls.d.ts +1 -0
  68. package/lib/projects/urls.js +3 -0
  69. package/lib/prompts/__tests__/projectAddPrompt.test.d.ts +1 -0
  70. package/lib/prompts/__tests__/projectAddPrompt.test.js +143 -0
  71. package/lib/prompts/__tests__/selectProjectTemplatePrompt.test.d.ts +1 -0
  72. package/lib/prompts/__tests__/selectProjectTemplatePrompt.test.js +160 -0
  73. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +1 -0
  74. package/lib/prompts/importDataFilePathPrompt.js +4 -2
  75. package/lib/prompts/installAppPrompt.d.ts +6 -1
  76. package/lib/prompts/installAppPrompt.js +6 -1
  77. package/lib/prompts/projectAddPrompt.js +1 -1
  78. package/lib/prompts/projectDevTargetAccountPrompt.js +1 -0
  79. package/lib/prompts/promptUtils.d.ts +7 -1
  80. package/lib/prompts/promptUtils.js +14 -1
  81. package/lib/prompts/selectProjectTemplatePrompt.js +1 -1
  82. package/lib/ui/index.js +3 -6
  83. package/mcp-server/server.js +2 -1
  84. package/mcp-server/tools/cms/HsCreateFunctionTool.d.ts +32 -0
  85. package/mcp-server/tools/cms/HsCreateFunctionTool.js +96 -0
  86. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +38 -0
  87. package/mcp-server/tools/cms/HsCreateModuleTool.js +118 -0
  88. package/mcp-server/tools/cms/HsCreateTemplateTool.d.ts +26 -0
  89. package/mcp-server/tools/cms/HsCreateTemplateTool.js +75 -0
  90. package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +32 -0
  91. package/mcp-server/tools/cms/HsFunctionLogsTool.js +76 -0
  92. package/mcp-server/tools/cms/HsListFunctionsTool.d.ts +23 -0
  93. package/mcp-server/tools/cms/HsListFunctionsTool.js +58 -0
  94. package/mcp-server/tools/cms/HsListTool.d.ts +23 -0
  95. package/mcp-server/tools/cms/HsListTool.js +58 -0
  96. package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.d.ts +1 -0
  97. package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +251 -0
  98. package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.d.ts +1 -0
  99. package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +224 -0
  100. package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.d.ts +1 -0
  101. package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +206 -0
  102. package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.d.ts +1 -0
  103. package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +183 -0
  104. package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.d.ts +1 -0
  105. package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +120 -0
  106. package/mcp-server/tools/cms/__tests__/HsListTool.test.d.ts +1 -0
  107. package/mcp-server/tools/cms/__tests__/HsListTool.test.js +120 -0
  108. package/mcp-server/tools/index.d.ts +1 -0
  109. package/mcp-server/tools/index.js +16 -0
  110. package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
  111. package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
  112. package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
  113. package/mcp-server/tools/project/CreateProjectTool.js +5 -5
  114. package/mcp-server/tools/project/DeployProjectTool.js +1 -1
  115. package/mcp-server/tools/project/DocFetchTool.js +3 -3
  116. package/mcp-server/tools/project/DocsSearchTool.js +3 -3
  117. package/mcp-server/tools/project/GetConfigValuesTool.js +4 -4
  118. package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
  119. package/mcp-server/tools/project/UploadProjectTools.js +2 -2
  120. package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
  121. package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
  122. package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
  123. package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
  124. package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +3 -3
  125. package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +3 -3
  126. package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +1 -1
  127. package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
  128. package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
  129. package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
  130. package/mcp-server/tools/project/constants.d.ts +1 -1
  131. package/mcp-server/tools/project/constants.js +14 -6
  132. package/package.json +5 -4
  133. package/types/LocalDev.d.ts +2 -1
  134. package/types/Projects.d.ts +1 -0
  135. package/types/Prompts.d.ts +1 -0
  136. package/ui/components/BoxWithTitle.d.ts +8 -0
  137. package/ui/components/BoxWithTitle.js +9 -0
  138. package/ui/components/HorizontalSelectPrompt.d.ts +8 -0
  139. package/ui/components/HorizontalSelectPrompt.js +30 -0
  140. package/ui/components/StatusMessageBoxes.d.ts +12 -0
  141. package/ui/components/StatusMessageBoxes.js +31 -0
  142. package/ui/lib/ui-testing-utils.d.ts +9 -0
  143. package/ui/lib/ui-testing-utils.js +47 -0
  144. package/ui/lib/useTerminalSize.d.ts +13 -0
  145. package/ui/lib/useTerminalSize.js +31 -0
  146. package/ui/styles.d.ts +18 -0
  147. package/ui/styles.js +18 -0
  148. package/ui/views/UiSandbox.d.ts +5 -0
  149. package/ui/views/UiSandbox.js +25 -0
  150. /package/lib/projects/__tests__/{buildAndDeploy.test.d.ts → deploy.test.d.ts} +0 -0
@@ -1,11 +1,10 @@
1
- import { deployProject, fetchProject, } from '@hubspot/local-dev-lib/api/projects';
1
+ import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
2
2
  import { getAccountConfig } from '@hubspot/local-dev-lib/config';
3
3
  import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
4
- import { useV3Api } from '../../lib/projects/buildAndDeploy.js';
4
+ import { useV3Api } from '../../lib/projects/platformVersion.js';
5
5
  import { trackCommandUsage } from '../../lib/usageTracking.js';
6
6
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
7
7
  import { getProjectConfig } from '../../lib/projects/config.js';
8
- import { pollDeployStatus } from '../../lib/projects/buildAndDeploy.js';
9
8
  import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
10
9
  import { promptUser } from '../../lib/prompts/promptUtils.js';
11
10
  import { uiBetaTag, uiLine } from '../../lib/ui/index.js';
@@ -13,54 +12,11 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
13
12
  import { uiLogger } from '../../lib/ui/logger.js';
14
13
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
15
14
  import { loadProfile, logProfileFooter, logProfileHeader, exitIfUsingProfiles, } from '../../lib/projectProfiles.js';
16
- import { PROJECT_ERROR_TYPES, PROJECT_DEPLOY_TEXT, } from '../../lib/constants.js';
15
+ import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
17
16
  import { commands } from '../../lang/en.js';
17
+ import { handleProjectDeploy, validateBuildIdForDeploy, logDeployErrors, } from '../../lib/projects/deploy.js';
18
18
  const command = 'deploy';
19
19
  const describe = uiBetaTag(commands.project.deploy.describe, false);
20
- function validateBuildId(buildId, deployedBuildId, latestBuildId, projectName, accountId) {
21
- if (Number(buildId) > latestBuildId) {
22
- return commands.project.deploy.errors.buildIdDoesNotExist(accountId, buildId, projectName);
23
- }
24
- if (Number(buildId) === deployedBuildId) {
25
- return commands.project.deploy.errors.buildAlreadyDeployed(accountId, buildId, projectName);
26
- }
27
- return true;
28
- }
29
- function logDeployErrors(errorData) {
30
- uiLogger.error(errorData.message);
31
- errorData.errors.forEach(err => {
32
- // This is how the pre-deploy check manifests itself in < 2025.2 projects
33
- if (err.subCategory === PROJECT_ERROR_TYPES.DEPLOY_CONTAINS_REMOVALS) {
34
- uiLogger.log(commands.project.deploy.errors.deployContainsRemovals(err.context.COMPONENT_NAME));
35
- }
36
- else {
37
- uiLogger.log(err.message);
38
- }
39
- });
40
- }
41
- function handleBlockedDeploy(deployResp) {
42
- const deployCanBeForced = deployResp.issues.every(issue => issue.blockingMessages.every(message => message.isWarning));
43
- uiLogger.log('');
44
- if (deployCanBeForced) {
45
- uiLogger.warn(commands.project.deploy.errors.deployWarningsHeader);
46
- uiLogger.log('');
47
- }
48
- else {
49
- uiLogger.error(commands.project.deploy.errors.deployBlockedHeader);
50
- uiLogger.log('');
51
- }
52
- deployResp.issues.forEach(issue => {
53
- if (issue.blockingMessages.length > 0) {
54
- issue.blockingMessages.forEach(message => {
55
- uiLogger.log(commands.project.deploy.errors.deployIssueComponentWarning(issue.uid, issue.componentTypeName, message.message));
56
- });
57
- }
58
- else {
59
- uiLogger.log(commands.project.deploy.errors.deployIssueComponentGeneric(issue.uid, issue.componentTypeName));
60
- }
61
- uiLogger.log('');
62
- });
63
- }
64
20
  async function handler(args) {
65
21
  const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, json: formatOutputAsJson, } = args;
66
22
  const accountConfig = getAccountConfig(derivedAccountId);
@@ -105,7 +61,7 @@ async function handler(args) {
105
61
  return process.exit(EXIT_CODES.ERROR);
106
62
  }
107
63
  if (buildIdToDeploy) {
108
- const validationResult = validateBuildId(buildIdToDeploy, deployedBuildId, latestBuild.buildId, projectName, targetAccountId);
64
+ const validationResult = validateBuildIdForDeploy(buildIdToDeploy, deployedBuildId, latestBuild.buildId, projectName, targetAccountId);
109
65
  if (validationResult !== true) {
110
66
  uiLogger.error(validationResult.toString());
111
67
  return process.exit(EXIT_CODES.ERROR);
@@ -122,7 +78,7 @@ async function handler(args) {
122
78
  default: latestBuild.buildId === deployedBuildId
123
79
  ? undefined
124
80
  : latestBuild.buildId,
125
- validate: buildId => validateBuildId(buildId, deployedBuildId, latestBuild.buildId, projectName, targetAccountId),
81
+ validate: buildId => validateBuildIdForDeploy(buildId, deployedBuildId, latestBuild.buildId, projectName, targetAccountId),
126
82
  });
127
83
  buildIdToDeploy = deployBuildIdPromptResponse.buildId;
128
84
  }
@@ -131,21 +87,13 @@ async function handler(args) {
131
87
  uiLogger.error(commands.project.deploy.errors.noBuildId);
132
88
  return process.exit(EXIT_CODES.ERROR);
133
89
  }
134
- const { data: deployResp } = await deployProject(targetAccountId, projectName, buildIdToDeploy, useV3Api(projectConfig?.platformVersion), forceOption);
135
- if (!deployResp || deployResp.buildResultType !== 'DEPLOY_QUEUED') {
136
- if (deployResp?.buildResultType === 'DEPLOY_BLOCKED') {
137
- handleBlockedDeploy(deployResp);
138
- process.exit(EXIT_CODES.ERROR);
139
- }
140
- else {
141
- uiLogger.error(commands.project.deploy.errors.deploy);
142
- }
90
+ const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, useV3Api(projectConfig?.platformVersion), forceOption);
91
+ if (!deployResult) {
143
92
  return process.exit(EXIT_CODES.ERROR);
144
93
  }
145
94
  else if (formatOutputAsJson) {
146
- jsonOutput.deployId = Number(deployResp.id);
95
+ jsonOutput.deployId = deployResult.deployId;
147
96
  }
148
- const deployResult = await pollDeployStatus(targetAccountId, projectName, Number(deployResp.id), buildIdToDeploy);
149
97
  if (deployResult.status === PROJECT_DEPLOY_TEXT.STATES.SUCCESS) {
150
98
  deploySuccess = true;
151
99
  }
@@ -5,9 +5,9 @@ import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
5
5
  import { uiBetaTag, uiLine } from '../../../lib/ui/index.js';
6
6
  import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
7
7
  import { unifiedProjectDevFlow } from './unifiedFlow.js';
8
- import { useV3Api } from '../../../lib/projects/buildAndDeploy.js';
8
+ import { useV3Api } from '../../../lib/projects/platformVersion.js';
9
9
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
10
- import { loadProfile, logProfileFooter, logProfileHeader, exitIfUsingProfiles, } from '../../../lib/projectProfiles.js';
10
+ import { loadProfile, exitIfUsingProfiles, } from '../../../lib/projectProfiles.js';
11
11
  import { commands } from '../../../lang/en.js';
12
12
  import { uiLogger } from '../../../lib/ui/logger.js';
13
13
  const command = 'dev';
@@ -33,19 +33,37 @@ async function handler(args) {
33
33
  process.exit(EXIT_CODES.ERROR);
34
34
  }
35
35
  validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV3);
36
- let targetProjectAccountId = (projectAccount && getAccountId(projectAccount)) ||
37
- (userProvidedAccount && derivedAccountId);
36
+ uiBetaTag(commands.project.dev.logs.betaMessage);
37
+ if (useV3) {
38
+ uiLogger.log(commands.project.dev.logs.learnMoreMessageV3);
39
+ }
40
+ else {
41
+ uiLogger.log(commands.project.dev.logs.learnMoreMessageLegacy);
42
+ }
43
+ let targetProjectAccountId;
38
44
  let profile;
45
+ // Using the new --projectAccount flag
46
+ if (projectAccount) {
47
+ targetProjectAccountId = getAccountId(projectAccount);
48
+ if (targetProjectAccountId) {
49
+ uiLogger.log('');
50
+ uiLogger.log(commands.project.dev.logs.projectAccountFlagExplanation(targetProjectAccountId));
51
+ }
52
+ // Using the legacy --account flag
53
+ }
54
+ else if (userProvidedAccount && derivedAccountId) {
55
+ targetProjectAccountId = derivedAccountId;
56
+ }
39
57
  if (!targetProjectAccountId && useV3Api(projectConfig.platformVersion)) {
40
58
  if (args.profile) {
41
- logProfileHeader(args.profile);
42
59
  profile = loadProfile(projectConfig, projectDir, args.profile);
43
60
  if (!profile) {
44
61
  uiLine();
45
62
  process.exit(EXIT_CODES.ERROR);
46
63
  }
47
64
  targetProjectAccountId = profile.accountId;
48
- logProfileFooter(profile);
65
+ uiLogger.log('');
66
+ uiLogger.log(commands.project.dev.logs.profileProjectAccountExplanation(targetProjectAccountId, args.profile));
49
67
  }
50
68
  else {
51
69
  // A profile must be specified if this project has profiles configured
@@ -55,10 +73,12 @@ async function handler(args) {
55
73
  if (!targetProjectAccountId) {
56
74
  // The user is not using profile or account flags, so we can use the derived accountId
57
75
  targetProjectAccountId = derivedAccountId;
76
+ if (useV3) {
77
+ uiLogger.log('');
78
+ uiLogger.log(commands.project.dev.logs.defaultProjectAccountExplanation(targetProjectAccountId));
79
+ }
58
80
  }
59
81
  trackCommandUsage('project-dev', {}, targetProjectAccountId);
60
- uiBetaTag(commands.project.dev.logs.betaMessage);
61
- uiLogger.log(commands.project.dev.logs.learnMoreLocalDevServer);
62
82
  if (useV3Api(projectConfig.platformVersion)) {
63
83
  const targetTestingAccountId = (testingAccount && getAccountId(testingAccount)) || undefined;
64
84
  await unifiedProjectDevFlow({
@@ -86,13 +106,13 @@ function projectDevBuilder(yargs) {
86
106
  description: commands.project.dev.options.profile,
87
107
  hidden: true,
88
108
  });
89
- yargs.options('testingAccount', {
109
+ yargs.options('testing-account', {
90
110
  type: 'string',
91
111
  description: commands.project.dev.options.testingAccount,
92
112
  hidden: true,
93
- implies: ['projectAccount'],
113
+ implies: ['project-account'],
94
114
  });
95
- yargs.options('projectAccount', {
115
+ yargs.options('project-account', {
96
116
  type: 'string',
97
117
  description: commands.project.dev.options.projectAccount,
98
118
  hidden: true,
@@ -100,8 +120,8 @@ function projectDevBuilder(yargs) {
100
120
  });
101
121
  yargs.example([['$0 project dev', commands.project.dev.examples.default]]);
102
122
  yargs.conflicts('profile', 'account');
103
- yargs.conflicts('profile', 'testingAccount');
104
- yargs.conflicts('profile', 'projectAccount');
123
+ yargs.conflicts('profile', 'testing-account');
124
+ yargs.conflicts('profile', 'project-account');
105
125
  return yargs;
106
126
  }
107
127
  export const builder = makeYargsBuilder(projectDevBuilder, command, describe, {
@@ -16,13 +16,13 @@ import LocalDevProcess from '../../../lib/projects/localDev/LocalDevProcess.js';
16
16
  import LocalDevWatcher from '../../../lib/projects/localDev/LocalDevWatcher.js';
17
17
  import { handleExit, handleKeypress } from '../../../lib/process.js';
18
18
  import { isTestAccountOrSandbox, isUnifiedAccount, } from '../../../lib/accountTypes.js';
19
- import { uiLine } from '../../../lib/ui/index.js';
20
19
  import { uiLogger } from '../../../lib/ui/logger.js';
21
20
  import { commands } from '../../../lang/en.js';
22
21
  import LocalDevWebsocketServer from '../../../lib/projects/localDev/LocalDevWebsocketServer.js';
23
22
  export async function unifiedProjectDevFlow({ args, targetProjectAccountId, providedTargetTestingAccountId, projectConfig, projectDir, }) {
24
23
  const env = getValidEnv(getEnv(targetProjectAccountId));
25
24
  let projectNodes;
25
+ let projectProfileData;
26
26
  // Get IR
27
27
  try {
28
28
  const intermediateRepresentation = await translateForLocalDev({
@@ -31,6 +31,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
31
31
  accountId: targetProjectAccountId,
32
32
  }, { profile: args.profile });
33
33
  projectNodes = intermediateRepresentation.intermediateNodesIndexedByUid;
34
+ projectProfileData = intermediateRepresentation.profileData;
34
35
  uiLogger.debug(util.inspect(projectNodes, false, null, true));
35
36
  }
36
37
  catch (e) {
@@ -69,13 +70,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
69
70
  !targetTestingAccountId &&
70
71
  targetProjectAccountIsTestAccountOrSandbox) {
71
72
  targetTestingAccountId = targetProjectAccountId;
73
+ uiLogger.log(commands.project.dev.logs.defaultSandboxOrDevTestTestingAccountExplanation(targetProjectAccountId));
72
74
  }
73
75
  else if (!targetTestingAccountId) {
74
- uiLogger.log('');
75
- uiLine();
76
- uiLogger.log(commands.project.dev.logs.accountTypeInformation);
77
- uiLogger.log(commands.project.dev.logs.learnMoreMessage);
78
- uiLine();
79
76
  uiLogger.log('');
80
77
  const accountType = await selectAccountTypePrompt(targetProjectAccountConfig);
81
78
  if (accountType === HUBSPOT_ACCOUNT_TYPES.DEVELOPER_TEST) {
@@ -101,6 +98,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
101
98
  targetTestingAccountId = targetProjectAccountId;
102
99
  }
103
100
  }
101
+ else {
102
+ uiLogger.log(commands.project.dev.logs.testingAccountFlagExplanation(targetTestingAccountId));
103
+ }
104
104
  // Check if project exists in HubSpot
105
105
  const { projectExists, project: uploadedProject } = await ensureProjectExists(targetProjectAccountId, projectConfig.name, {
106
106
  allowCreate: false,
@@ -109,7 +109,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
109
109
  let project = uploadedProject;
110
110
  SpinniesManager.init();
111
111
  if (projectExists && project) {
112
- await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes);
112
+ await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes, args.profile);
113
113
  }
114
114
  else {
115
115
  project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, false, false);
@@ -118,6 +118,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
118
118
  // End setup, start local dev process
119
119
  const localDevProcess = new LocalDevProcess({
120
120
  initialProjectNodes: projectNodes,
121
+ initialProjectProfileData: projectProfileData,
121
122
  debug: args.debug,
122
123
  profile: args.profile,
123
124
  targetProjectAccountId,
@@ -2,14 +2,14 @@ import chalk from 'chalk';
2
2
  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
- import { useV3Api } from '../../lib/projects/buildAndDeploy.js';
5
+ import { useV3Api } from '../../lib/projects/platformVersion.js';
6
6
  import { uiBetaTag, 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';
10
10
  import { handleProjectUpload } from '../../lib/projects/upload.js';
11
11
  import { loadAndValidateProfile } from '../../lib/projectProfiles.js';
12
- import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/buildAndDeploy.js';
12
+ import { displayWarnLogs, pollProjectBuildAndDeploy, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
13
13
  import { i18n } from '../../lib/lang.js';
14
14
  import { PROJECT_ERROR_TYPES } from '../../lib/constants.js';
15
15
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
  import { getAccountConfig } from '@hubspot/local-dev-lib/config';
3
- import { useV3Api } from '../../lib/projects/buildAndDeploy.js';
3
+ import { useV3Api } from '../../lib/projects/platformVersion.js';
4
4
  import { trackCommandUsage } from '../../lib/usageTracking.js';
5
5
  import { uiLogger } from '../../lib/ui/logger.js';
6
6
  import { getProjectConfig, validateProjectConfig as validateProjectConfig, } from '../../lib/projects/config.js';
@@ -1,6 +1,6 @@
1
1
  import { cancelStagedBuild, fetchProjectBuilds, } from '@hubspot/local-dev-lib/api/projects';
2
2
  import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
3
- import { useV3Api } from '../../lib/projects/buildAndDeploy.js';
3
+ import { useV3Api } from '../../lib/projects/platformVersion.js';
4
4
  import { uiCommandReference, uiLink, uiBetaTag } from '../../lib/ui/index.js';
5
5
  import { i18n } from '../../lib/lang.js';
6
6
  import { createWatcher } from '../../lib/projects/watch.js';
@@ -11,7 +11,7 @@ import { trackCommandUsage } from '../../lib/usageTracking.js';
11
11
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
12
12
  import { logFeedbackMessage } from '../../lib/projects/ui.js';
13
13
  import { handleProjectUpload } from '../../lib/projects/upload.js';
14
- import { pollBuildStatus, pollDeployStatus, } from '../../lib/projects/buildAndDeploy.js';
14
+ import { pollBuildStatus, pollDeployStatus, } from '../../lib/projects/pollProjectBuildAndDeploy.js';
15
15
  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';
package/lang/en.d.ts CHANGED
@@ -23,7 +23,8 @@ export declare const commands: {
23
23
  };
24
24
  readonly startTitle: "Welcome to HubSpot Development!";
25
25
  readonly verboseDescribe: "A step-by-step command to get you started with a HubSpot project.";
26
- readonly startDescription: "You can use the HubSpot CLI to build apps, CMS themes, and more.";
26
+ readonly startDescription: "You can use the HubSpot CLI to build apps, CMS themes, and more.\n";
27
+ readonly guideOverview: (accountName: string) => string;
27
28
  readonly designManager: "To onboard with CMS, please visit the HubSpot Design Manager in your account and follow the checklist items.";
28
29
  readonly openDesignManager: "Click here to go to the HubSpot Design Manager";
29
30
  readonly openDesignManagerPrompt: "Open Design Manager in your browser?";
@@ -1009,10 +1010,15 @@ Profiles enable you to reference variables in your component configuration files
1009
1010
  readonly logs: {
1010
1011
  readonly betaMessage: "HubSpot projects local development";
1011
1012
  readonly placeholderAccountSelection: "Using default account as target account (for now)";
1012
- readonly learnMoreLocalDevServer: string;
1013
1013
  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.";
1014
- readonly learnMoreMessage: `
1015
- Visit our ${string} to learn more.`;
1014
+ readonly learnMoreMessageV3: `Learn more about ${string} | ${string}`;
1015
+ readonly learnMoreMessageLegacy: string;
1016
+ readonly profileProjectAccountExplanation: (accountId: number, profileName: string) => string;
1017
+ readonly defaultProjectAccountExplanation: (accountId: number) => string;
1018
+ readonly projectAccountFlagExplanation: (accountId: number) => string;
1019
+ readonly accountFlagExplanation: (accountId: number) => string;
1020
+ readonly defaultSandboxOrDevTestTestingAccountExplanation: (accountId: number) => string;
1021
+ readonly testingAccountFlagExplanation: (accountId: number) => string;
1016
1022
  };
1017
1023
  readonly errors: {
1018
1024
  readonly noProjectConfig: "No project detected. Please run this command again from a project directory.";
@@ -1022,8 +1028,8 @@ Visit our ${string} to learn more.`;
1022
1028
  readonly noRunnableComponents: `No supported components were found in this project. Run ${string} to see a list of available components and add one to your project.`;
1023
1029
  readonly accountNotCombined: `
1024
1030
  Local development of unified apps is currently only compatible with accounts that are opted into the unified apps beta. Make sure that this account is opted in or switch accounts using ${string}.`;
1025
- readonly unsupportedAccountFlagLegacy: "The --projectAccount and --testingAccount flags are not supported for projects with platform versions earlier than 2025.2.";
1026
- readonly unsupportedAccountFlagV3: "The --account flag is is not supported supported for projects with platform versions 2025.2 and newer. Use --testingAccount and --projectAccount flags to specify accounts to use for local dev";
1031
+ readonly unsupportedAccountFlagLegacy: "The --project-account and --testing-account flags are not supported for projects with platform versions earlier than 2025.2.";
1032
+ readonly unsupportedAccountFlagV3: "The --account flag is is not supported supported for projects with platform versions 2025.2 and newer. Use --testing-account and --project-account flags to specify accounts to use for local dev";
1027
1033
  };
1028
1034
  readonly examples: {
1029
1035
  readonly default: "Start local dev for the current project";
@@ -1183,9 +1189,11 @@ ${string}`;
1183
1189
  readonly success: (componentName: string, multiple?: boolean) => string;
1184
1190
  readonly error: {
1185
1191
  readonly failedToDownloadComponent: "Failed to download project. Please try again later.";
1192
+ readonly invalidComponentType: (componentType: string) => string;
1186
1193
  readonly maxExceeded: (maxCount: number) => string;
1187
1194
  readonly authTypeNotAllowed: (authType: string) => string;
1188
1195
  readonly distributionNotAllowed: (dist: string) => string;
1196
+ readonly portalDoesNotHaveAccessToThisFeature: (accountId: number) => string;
1189
1197
  readonly locationInProject: "This command must be run from within a project directory.";
1190
1198
  readonly failedToFetchComponentList: "Failed to fetch the list of available features. Please try again later.";
1191
1199
  readonly projectContainsPublicApp: "This project contains a public app. This command is currently only compatible with projects that contain private apps.";
@@ -2557,6 +2565,15 @@ export declare const lib: {
2557
2565
  readonly autoInstallDeclined: "You must install your app on your target test account to proceed with local development.";
2558
2566
  readonly autoInstallSuccess: (appName: string, targetTestAccountId: number) => string;
2559
2567
  readonly autoInstallError: (appName: string, targetTestAccountId: number) => string;
2568
+ readonly fetchAppData: {
2569
+ readonly checking: (appName: string) => string;
2570
+ readonly success: (appName: string, accountId: number) => string;
2571
+ readonly notInstalled: (appName: string, accountId: number) => string;
2572
+ readonly activeInstallations: (appName: string, installCount: number) => string;
2573
+ readonly error: "An error occurred while checking installations for your app";
2574
+ };
2575
+ readonly distributionChanged: `Your app's distribution type has been changed from private to marketplace. Once uploaded, this change cannot be reversed. Before uploading your project, confirm that you want to ${string} change your app's distribution type. This will uninstall your app from all accounts.`;
2576
+ readonly authTypeChanged: `Your app's auth type has been changed from static to oauth. Once uploaded, this change cannot be reversed. Before uploading your project, confirm that you want to ${string} change your app's auth type. This will uninstall your app from all accounts.`;
2560
2577
  };
2561
2578
  readonly LocalDevWebsocketServer: {
2562
2579
  readonly errors: {
@@ -2584,7 +2601,7 @@ export declare const lib: {
2584
2601
  readonly checking: "Checking if your deployed build is up to date...";
2585
2602
  readonly upToDate: "Deployed build is up to date.";
2586
2603
  readonly notUpToDate: "Your project contains undeployed local changes.";
2587
- readonly notUpToDateExplanation: `Run ${string} to upload these changes to HubSpot, then re-run ${string} to continue local development.`;
2604
+ readonly notUpToDateExplanation: (profile?: string) => string;
2588
2605
  };
2589
2606
  readonly createNewProjectForLocalDev: {
2590
2607
  readonly projectMustExistExplanation: (projectName: string, accountId: number) => string;
@@ -2616,11 +2633,11 @@ export declare const lib: {
2616
2633
  readonly notAuthedError: (parentAccountId: number | string, accountIdentifier: string) => string;
2617
2634
  };
2618
2635
  readonly selectAccountTypePrompt: {
2619
- readonly message: "[--account] Choose the type of account to test on";
2620
- readonly developerTestAccountOption: "Test on a developer test account";
2636
+ readonly message: "[--testing-account] Choose the type of account to test on";
2637
+ readonly developerTestAccountOption: "Test on a developer test account (recommended)";
2621
2638
  readonly sandboxAccountOption: "Test on a sandbox account";
2622
2639
  readonly sandboxAccountOptionDisabled: "Disabled - requires access to sandbox accounts";
2623
- readonly productionAccountOption: `<${string} Test on this account ${string}>`;
2640
+ readonly productionAccountOption: (accountId?: number) => string;
2624
2641
  };
2625
2642
  readonly confirmDefaultAccountIsTarget: {
2626
2643
  readonly configError: `An error occurred while reading the default account from your config. Run ${string} to re-auth this account`;
@@ -2684,6 +2701,11 @@ Run ${string} to upgrade to version ${string}`;
2684
2701
  readonly add: {
2685
2702
  readonly nothingAdded: "No features added.";
2686
2703
  };
2704
+ readonly updateHsMetaFilesWithAutoGeneratedFields: {
2705
+ readonly header: "Created the following components and features:";
2706
+ readonly applicationLog: (componentType: string, uid: string, name: string) => string;
2707
+ readonly componentLog: (componentType: string, uid: string) => string;
2708
+ };
2687
2709
  readonly validateProjectConfig: {
2688
2710
  readonly configNotFound: `Unable to locate a project configuration file. Try running again from a project directory, or run ${string} to create a new project.`;
2689
2711
  readonly configMissingFields: "The project configuration file is missing required fields.";
@@ -3141,8 +3163,9 @@ Run ${string} to upgrade to version ${string}`;
3141
3163
  };
3142
3164
  };
3143
3165
  readonly installAppPrompt: {
3144
- readonly explanation: "Local development requires this app to be installed in the target test account";
3166
+ readonly explanation: "Local development requires this app to be installed in the target test account.";
3145
3167
  readonly reinstallExplanation: "This app's required scopes have been updated since it was last installed on the target test account. To avoid issues with local development, we recommend reinstalling the app with the updated scopes.";
3168
+ readonly staticAuthExplanation: (projectAccountId: number, testingAccountId: number, projectName: string, appUid: string) => string;
3146
3169
  readonly prompt: "Open HubSpot to install this app?";
3147
3170
  readonly autoPrompt: "Install this app in your target test account?";
3148
3171
  readonly reinstallPrompt: "Open HubSpot to reinstall this app?";
@@ -3363,7 +3386,7 @@ Run ${string} to upgrade to version ${string}`;
3363
3386
  readonly componentsToBeMigrated: (components: string) => string;
3364
3387
  readonly componentsThatWillNotBeMigrated: (components: string) => string;
3365
3388
  readonly sourceContentsMoved: (newLocation: string) => string;
3366
- readonly projectMigrationWarningTitle: "⚠️ Important: Migrating to platformVersion 2025.2 is irreversible ⚠️";
3389
+ readonly projectMigrationWarningTitle: "Important: Migrating to platformVersion 2025.2 is irreversible";
3367
3390
  readonly projectMigrationWarning: string;
3368
3391
  readonly success: {
3369
3392
  readonly downloadedProject: (projectName: string, projectDest: string) => string;
@@ -3378,7 +3401,7 @@ Run ${string} to upgrade to version ${string}`;
3378
3401
  readonly themesAndAppsNotAllowed: "Support for migrating projects containing both themes and apps to the latest platform version is coming soon. Try again later.";
3379
3402
  readonly multipleApps: "Multiple apps found in project, this is not allowed in 2025.2";
3380
3403
  readonly alreadyExists: (projectName: string) => string;
3381
- readonly failedToMigrateThemes: "Failed to migrate project themes. Please verify that you have propoerly formatted themes before trying again.";
3404
+ readonly failedToMigrateThemes: "Failed to migrate project themes. Please verify that your themes are properly formatted before trying again.";
3382
3405
  readonly failedToUpdateProjectConfig: "Failed to update project config file. Please update the platformVersion in the project config file manually.";
3383
3406
  };
3384
3407
  readonly unmigratableReasons: {