@hubspot/cli 8.0.11-experimental.1 → 8.0.11-experimental.2

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 (86) hide show
  1. package/api/migrate.js +3 -3
  2. package/bin/cli.js +3 -0
  3. package/commands/app/migrate.js +4 -4
  4. package/commands/getStarted.js +2 -2
  5. package/commands/project/add.js +3 -3
  6. package/commands/project/create.js +10 -7
  7. package/commands/project/delete.js +2 -2
  8. package/commands/project/deploy.js +4 -3
  9. package/commands/project/dev/index.js +5 -4
  10. package/commands/project/info.js +2 -2
  11. package/commands/project/migrate.js +5 -5
  12. package/commands/project/profile/add.js +2 -2
  13. package/commands/project/profile/delete.js +2 -2
  14. package/commands/project/upload.js +3 -3
  15. package/commands/project/validate.js +2 -2
  16. package/commands/project/watch.js +2 -2
  17. package/commands/project.js +6 -3
  18. package/commands/testAccount/create.js +4 -4
  19. package/lang/en.d.ts +1 -0
  20. package/lang/en.js +5 -4
  21. package/lib/app/migrate.js +7 -0
  22. package/lib/doctor/Doctor.js +2 -2
  23. package/lib/getStartedV2Actions.js +2 -2
  24. package/lib/projects/ProjectLogsManager.js +2 -2
  25. package/lib/projects/create/index.js +2 -2
  26. package/lib/projects/create/legacy.js +2 -2
  27. package/lib/projects/create/v2.js +2 -2
  28. package/lib/projects/delete.js +2 -2
  29. package/lib/projects/deploy.d.ts +1 -1
  30. package/lib/projects/deploy.js +2 -2
  31. package/lib/projects/upload.js +4 -4
  32. package/lib/theme/cmsDevServerProcess.js +1 -1
  33. package/mcp-server/Tool.d.ts +15 -0
  34. package/mcp-server/Tool.js +53 -0
  35. package/mcp-server/server.js +5 -3
  36. package/mcp-server/tools/cms/HsCreateFunctionTool.d.ts +4 -2
  37. package/mcp-server/tools/cms/HsCreateFunctionTool.js +8 -6
  38. package/mcp-server/tools/cms/HsCreateModuleTool.d.ts +4 -2
  39. package/mcp-server/tools/cms/HsCreateModuleTool.js +8 -6
  40. package/mcp-server/tools/cms/HsCreateTemplateTool.d.ts +4 -2
  41. package/mcp-server/tools/cms/HsCreateTemplateTool.js +8 -6
  42. package/mcp-server/tools/cms/HsFunctionLogsTool.d.ts +4 -2
  43. package/mcp-server/tools/cms/HsFunctionLogsTool.js +8 -6
  44. package/mcp-server/tools/cms/HsListFunctionsTool.d.ts +4 -2
  45. package/mcp-server/tools/cms/HsListFunctionsTool.js +8 -6
  46. package/mcp-server/tools/cms/HsListTool.d.ts +4 -2
  47. package/mcp-server/tools/cms/HsListTool.js +8 -6
  48. package/mcp-server/tools/index.d.ts +3 -2
  49. package/mcp-server/tools/index.js +22 -22
  50. package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +6 -4
  51. package/mcp-server/tools/project/AddFeatureToProjectTool.js +8 -6
  52. package/mcp-server/tools/project/CreateProjectTool.d.ts +6 -4
  53. package/mcp-server/tools/project/CreateProjectTool.js +9 -7
  54. package/mcp-server/tools/project/CreateTestAccountTool.d.ts +4 -2
  55. package/mcp-server/tools/project/CreateTestAccountTool.js +20 -8
  56. package/mcp-server/tools/project/DeployProjectTool.d.ts +4 -2
  57. package/mcp-server/tools/project/DeployProjectTool.js +4 -6
  58. package/mcp-server/tools/project/DocFetchTool.d.ts +4 -2
  59. package/mcp-server/tools/project/DocFetchTool.js +8 -6
  60. package/mcp-server/tools/project/DocsSearchTool.d.ts +9 -3
  61. package/mcp-server/tools/project/DocsSearchTool.js +32 -9
  62. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +4 -2
  63. package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +8 -6
  64. package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +4 -2
  65. package/mcp-server/tools/project/GetApplicationInfoTool.js +8 -6
  66. package/mcp-server/tools/project/GetBuildLogsTool.d.ts +4 -2
  67. package/mcp-server/tools/project/GetBuildLogsTool.js +8 -6
  68. package/mcp-server/tools/project/GetBuildStatusTool.d.ts +4 -2
  69. package/mcp-server/tools/project/GetBuildStatusTool.js +8 -6
  70. package/mcp-server/tools/project/GetConfigValuesTool.d.ts +4 -2
  71. package/mcp-server/tools/project/GetConfigValuesTool.js +12 -7
  72. package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +4 -2
  73. package/mcp-server/tools/project/GuidedWalkthroughTool.js +4 -6
  74. package/mcp-server/tools/project/UploadProjectTools.d.ts +4 -2
  75. package/mcp-server/tools/project/UploadProjectTools.js +9 -7
  76. package/mcp-server/tools/project/ValidateProjectTool.d.ts +4 -2
  77. package/mcp-server/tools/project/ValidateProjectTool.js +8 -6
  78. package/mcp-server/tools/project/constants.d.ts +2 -2
  79. package/mcp-server/types.d.ts +0 -7
  80. package/mcp-server/types.js +1 -13
  81. package/mcp-server/utils/logger.d.ts +10 -0
  82. package/mcp-server/utils/logger.js +29 -0
  83. package/mcp-server/utils/toolUsageTracking.js +0 -2
  84. package/package.json +5 -5
  85. package/lib/projects/platformVersion.d.ts +0 -9
  86. package/lib/projects/platformVersion.js +0 -39
package/api/migrate.js CHANGED
@@ -1,4 +1,4 @@
1
- import { PLATFORM_VERSIONS, } from '@hubspot/local-dev-lib/constants/projects';
1
+ import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
2
2
  import { http } from '@hubspot/local-dev-lib/http';
3
3
  const MIGRATIONS_API_PATH_V2 = 'dfs/migrations/v2';
4
4
  export const CLI_UNMIGRATABLE_REASONS = {
@@ -20,8 +20,8 @@ export async function listAppsForMigration(accountId, platformVersion, appId) {
20
20
  });
21
21
  }
22
22
  function mapPlatformVersionToEnum(platformVersion) {
23
- if (platformVersion === PLATFORM_VERSIONS.unstable) {
24
- return PLATFORM_VERSIONS.unstable.toUpperCase();
23
+ if (platformVersion === PLATFORM_VERSIONS.UNSTABLE) {
24
+ return PLATFORM_VERSIONS.UNSTABLE.toUpperCase();
25
25
  }
26
26
  const reformattedPlatformVersion = platformVersion
27
27
  .replaceAll('.', '_')
package/bin/cli.js CHANGED
@@ -35,6 +35,7 @@ import apiCommand from '../commands/api.js';
35
35
  import { uiLogger } from '../lib/ui/logger.js';
36
36
  import { initializeSpinniesManager } from '../lib/middleware/spinniesMiddleware.js';
37
37
  import { addCommandSuggestions } from '../lib/commandSuggestion.js';
38
+ import { pkg } from '../lib/jsonLoader.js';
38
39
  function getTerminalWidth() {
39
40
  const width = yargs().terminalWidth();
40
41
  if (width >= 100)
@@ -121,6 +122,8 @@ const argv = yargs(process.argv.slice(2))
121
122
  const argvWithSuggestions = addCommandSuggestions(argv)
122
123
  .help()
123
124
  .alias('h', 'help')
125
+ .version(pkg.version)
126
+ .alias('v', 'version')
124
127
  .recommendCommands()
125
128
  .demandCommand(1, '')
126
129
  .wrap(getTerminalWidth())
@@ -1,5 +1,5 @@
1
1
  import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
2
- import { PLATFORM_VERSIONS } from '@hubspot/local-dev-lib/constants/projects';
2
+ import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
3
3
  import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
4
4
  import { trackCommandMetadataUsage } from '../../lib/usageTracking.js';
5
5
  import { commands } from '../../lang/en.js';
@@ -9,7 +9,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
9
9
  import { migrateApp } from '../../lib/app/migrate.js';
10
10
  import { getIsInProject } from '../../lib/projects/config.js';
11
11
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
12
- const { v2025_2, v2026_03_beta, v2026_03 } = PLATFORM_VERSIONS;
12
+ const { v2025_2, v2026_03_BETA, v2026_03 } = PLATFORM_VERSIONS;
13
13
  const command = 'migrate';
14
14
  const describe = commands.project.migrateApp.describe;
15
15
  export function handlerGenerator(commandTrackingName) {
@@ -29,7 +29,7 @@ export function handlerGenerator(commandTrackingName) {
29
29
  return exit(EXIT_CODES.ERROR);
30
30
  }
31
31
  args.platformVersion = unstable
32
- ? PLATFORM_VERSIONS.unstable
32
+ ? PLATFORM_VERSIONS.UNSTABLE
33
33
  : platformVersion;
34
34
  await migrateApp(derivedAccountId, args);
35
35
  }
@@ -67,7 +67,7 @@ function appMigrateBuilder(yargs) {
67
67
  },
68
68
  'platform-version': {
69
69
  type: 'string',
70
- choices: [v2025_2, v2026_03_beta, v2026_03],
70
+ choices: [v2025_2, v2026_03_BETA, v2026_03],
71
71
  default: v2026_03,
72
72
  },
73
73
  unstable: {
@@ -16,7 +16,6 @@ import { uiLogger } from '../lib/ui/logger.js';
16
16
  import { trackCommandMetadataUsage } from '../lib/usageTracking.js';
17
17
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
18
18
  import { makeYargsHandlerWithUsageTracking } from '../lib/yargs/makeYargsHandlerWithUsageTracking.js';
19
- import { isV2Project } from '../lib/projects/platformVersion.js';
20
19
  import { pollProjectBuildAndDeploy } from '../lib/projects/pollProjectBuildAndDeploy.js';
21
20
  import { fetchPublicAppsForPortal } from '@hubspot/local-dev-lib/api/appsDev';
22
21
  import { getConfigAccountEnvironment } from '@hubspot/local-dev-lib/config';
@@ -24,6 +23,7 @@ import { getStaticAuthAppInstallUrl } from '../lib/app/urls.js';
24
23
  import ProjectValidationError from '../lib/errors/ProjectValidationError.js';
25
24
  import { openLink } from '../lib/links.js';
26
25
  import { runGetStartedV2 } from '../lib/getStarted/getStartedV2.js';
26
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
27
27
  const command = 'get-started';
28
28
  const describe = commands.getStarted.describe;
29
29
  async function handler(args) {
@@ -204,7 +204,7 @@ async function handler(args) {
204
204
  uploadMessage: 'Initial upload from get-started command',
205
205
  forceCreate: true, // Auto-create project on HubSpot
206
206
  isUploadCommand: false,
207
- sendIR: isV2Project(newProjectConfig.platformVersion),
207
+ sendIR: !isLegacyProject(newProjectConfig.platformVersion),
208
208
  skipValidation: false,
209
209
  });
210
210
  if (uploadError) {
@@ -5,7 +5,7 @@ import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
5
5
  import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
6
6
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
7
7
  import { commands } from '../../lang/en.js';
8
- import { isV2Project } from '../../lib/projects/platformVersion.js';
8
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
9
9
  import { legacyAddComponent } from '../../lib/projects/add/legacyAddComponent.js';
10
10
  import { v2AddComponent } from '../../lib/projects/add/v2AddComponent.js';
11
11
  import { marketplaceDistribution, oAuth, privateDistribution, staticAuth, } from '../../lib/constants.js';
@@ -20,8 +20,8 @@ async function handler(args) {
20
20
  uiLogger.error(commands.project.add.error.locationInProject);
21
21
  return exit(EXIT_CODES.ERROR);
22
22
  }
23
- const isV2ProjectCreate = isV2Project(projectConfig.platformVersion);
24
- if (isV2ProjectCreate) {
23
+ const isLegacyProjectCreate = isLegacyProject(projectConfig.platformVersion);
24
+ if (!isLegacyProjectCreate) {
25
25
  await v2AddComponent(args, projectDir, projectConfig, derivedAccountId);
26
26
  }
27
27
  else {
@@ -2,25 +2,23 @@ import path from 'path';
2
2
  import fs from 'fs-extra';
3
3
  import { cloneGithubRepo } from '@hubspot/local-dev-lib/github';
4
4
  import { getCwd } from '@hubspot/local-dev-lib/path';
5
+ import { getProjectMetadata, } from '@hubspot/project-parsing-lib/projects';
6
+ import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
5
7
  import { writeProjectConfig, getProjectConfig, } from '../../lib/projects/config.js';
6
8
  import { EMPTY_PROJECT_TEMPLATE_NAME } from '../../lib/projects/create/legacy.js';
7
9
  import { generateComponentPaths } from '../../lib/projects/create/v2.js';
8
- import { PROJECT_WITH_APP, EMPTY_PROJECT } from '../../lib/constants.js';
9
10
  import { debugError, logError } from '../../lib/errorHandlers/index.js';
10
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
11
- import { PROJECT_CONFIG_FILE, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, marketplaceDistribution, privateDistribution, oAuth, staticAuth, DEFAULT_PROJECT_TEMPLATE_BRANCH, } from '../../lib/constants.js';
12
+ import { PROJECT_CONFIG_FILE, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, marketplaceDistribution, privateDistribution, oAuth, staticAuth, DEFAULT_PROJECT_TEMPLATE_BRANCH, PROJECT_WITH_APP, EMPTY_PROJECT, } from '../../lib/constants.js';
12
13
  import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
13
14
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
14
- import { PLATFORM_VERSIONS } from '@hubspot/local-dev-lib/constants/projects';
15
15
  import { commands } from '../../lang/en.js';
16
16
  import { uiLogger } from '../../lib/ui/logger.js';
17
17
  import { handleProjectCreationFlow, } from '../../lib/projects/create/index.js';
18
- import { getProjectMetadata, } from '@hubspot/project-parsing-lib/projects';
19
18
  import { updateHsMetaFilesWithAutoGeneratedFields } from '../../lib/projects/components.js';
20
19
  import SpinniesManager from '../../lib/ui/SpinniesManager.js';
21
20
  const command = ['create', 'init'];
22
21
  const describe = commands.project.create.describe;
23
- const { v2025_1, v2025_2, v2026_03_beta, v2026_03 } = PLATFORM_VERSIONS;
24
22
  async function handler(args) {
25
23
  const { platformVersion, templateSource, exit, addUsageMetadata } = args;
26
24
  if (templateSource && !templateSource.includes('/')) {
@@ -125,8 +123,13 @@ function projectCreateBuilder(yargs) {
125
123
  'platform-version': {
126
124
  describe: commands.project.create.options.platformVersion.describe,
127
125
  type: 'string',
128
- choices: [v2025_1, v2025_2, v2026_03_beta, v2026_03],
129
- default: v2026_03,
126
+ choices: [
127
+ PLATFORM_VERSIONS.v2025_1,
128
+ PLATFORM_VERSIONS.v2025_2,
129
+ PLATFORM_VERSIONS.v2026_03_BETA,
130
+ PLATFORM_VERSIONS.v2026_03,
131
+ ],
132
+ default: PLATFORM_VERSIONS.v2026_03,
130
133
  },
131
134
  'project-base': {
132
135
  describe: commands.project.create.options.projectBase.describe,
@@ -5,7 +5,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
5
5
  import { renderInline } from '../../ui/render.js';
6
6
  import { getWarningBox } from '../../ui/components/StatusMessageBoxes.js';
7
7
  import { commands } from '../../lang/en.js';
8
- import { isV2Project } from '../../lib/projects/platformVersion.js';
8
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
9
9
  import { isPromptExitError } from '../../lib/errors/PromptExitError.js';
10
10
  import { resolveProjectName, checkDeployedComponents, deleteDeployedComponents, confirmDeletion, handleProjectDeletion, } from '../../lib/projects/delete.js';
11
11
  const command = 'delete';
@@ -23,7 +23,7 @@ async function handler(args) {
23
23
  if (!force) {
24
24
  await confirmDeletion(projectName, derivedAccountId, projectId);
25
25
  }
26
- if (isV2Project(platformVersion) && hasUnifiedComponents) {
26
+ if (!isLegacyProject(platformVersion) && hasUnifiedComponents) {
27
27
  await deleteDeployedComponents(derivedAccountId, projectName);
28
28
  }
29
29
  await handleProjectDeletion(derivedAccountId, projectName);
@@ -1,7 +1,7 @@
1
1
  import { fetchProject } from '@hubspot/local-dev-lib/api/projects';
2
2
  import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
3
3
  import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
4
- import { isV2Project } from '../../lib/projects/platformVersion.js';
4
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
5
5
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
6
6
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
7
7
  import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
@@ -31,7 +31,8 @@ async function handler(args) {
31
31
  isInProjectDirectory = true;
32
32
  }
33
33
  catch (e) { }
34
- if (isInProjectDirectory && isV2Project(projectConfig?.platformVersion)) {
34
+ if (isInProjectDirectory &&
35
+ !isLegacyProject(projectConfig?.platformVersion)) {
35
36
  try {
36
37
  const profileName = await projectProfilePrompt(projectDir, projectConfig, profileOption, !!useEnvOption);
37
38
  if (profileName) {
@@ -97,7 +98,7 @@ async function handler(args) {
97
98
  uiLogger.error(commands.project.deploy.errors.noBuildId);
98
99
  return exit(EXIT_CODES.ERROR);
99
100
  }
100
- const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, isV2Project(projectConfig?.platformVersion), forceOption);
101
+ const deployResult = await handleProjectDeploy(targetAccountId, projectName, buildIdToDeploy, isLegacyProject(projectConfig?.platformVersion), forceOption);
101
102
  if (!deployResult) {
102
103
  return exit(EXIT_CODES.ERROR);
103
104
  }
@@ -5,7 +5,7 @@ import { uiLine } from '../../../lib/ui/index.js';
5
5
  import { makeYargsHandlerWithUsageTracking } from '../../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
6
6
  import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
7
7
  import { unifiedProjectDevFlow } from './unifiedFlow.js';
8
- import { isV2Project } from '../../../lib/projects/platformVersion.js';
8
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
9
9
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
10
10
  import { loadAndValidateProfile } from '../../../lib/projects/projectProfiles.js';
11
11
  import { commands } from '../../../lang/en.js';
@@ -34,7 +34,7 @@ async function handler(args) {
34
34
  logError(error);
35
35
  return exit(EXIT_CODES.ERROR);
36
36
  }
37
- const useV2Projects = isV2Project(projectConfig.platformVersion);
37
+ const useV2Projects = !isLegacyProject(projectConfig.platformVersion);
38
38
  if (!projectDir) {
39
39
  uiLogger.error(commands.project.dev.errors.noProjectConfig);
40
40
  return exit(EXIT_CODES.ERROR);
@@ -69,7 +69,8 @@ async function handler(args) {
69
69
  targetProjectAccountId = derivedAccountId;
70
70
  }
71
71
  // Determine profile name: from flag or prompt
72
- if (!targetProjectAccountId && isV2Project(projectConfig.platformVersion)) {
72
+ if (!targetProjectAccountId &&
73
+ !isLegacyProject(projectConfig.platformVersion)) {
73
74
  const profileName = await projectProfilePrompt(projectDir, projectConfig, profileOption);
74
75
  if (profileName) {
75
76
  try {
@@ -95,7 +96,7 @@ async function handler(args) {
95
96
  }
96
97
  addUsageMetadata({ accountId: targetProjectAccountId ?? undefined });
97
98
  try {
98
- if (isV2Project(projectConfig.platformVersion)) {
99
+ if (!isLegacyProject(projectConfig.platformVersion)) {
99
100
  const targetTestingAccountId = testingAccount
100
101
  ? getConfigAccountIfExists(testingAccount)?.accountId
101
102
  : undefined;
@@ -6,7 +6,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
6
6
  import { uiLogger } from '../../lib/ui/logger.js';
7
7
  import { commands } from '../../lang/en.js';
8
8
  import { getProjectConfig } from '../../lib/projects/config.js';
9
- import { isV2Project } from '../../lib/projects/platformVersion.js';
9
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
10
10
  import { getProjectInfo, logProjectInfo, } from '../../lib/projects/projectInfo.js';
11
11
  const command = 'info';
12
12
  const describe = commands.project.info.describe;
@@ -18,7 +18,7 @@ async function handler(args) {
18
18
  uiLogger.error(commands.project.info.errors.noProjectConfig);
19
19
  return exit(EXIT_CODES.ERROR);
20
20
  }
21
- if (!isV2Project(projectConfig.platformVersion)) {
21
+ if (isLegacyProject(projectConfig.platformVersion)) {
22
22
  uiLogger.error(commands.project.info.errors.unsupportedPlatformVersion(projectConfig.platformVersion));
23
23
  return exit(EXIT_CODES.ERROR);
24
24
  }
@@ -1,7 +1,7 @@
1
1
  import { makeYargsHandlerWithUsageTracking } from '../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
2
2
  import { migrateApp } from '../../lib/app/migrate.js';
3
3
  import { getProjectConfig } from '../../lib/projects/config.js';
4
- import { PLATFORM_VERSIONS } from '@hubspot/local-dev-lib/constants/projects';
4
+ import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
5
5
  import { logError } from '../../lib/errorHandlers/index.js';
6
6
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
7
7
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
@@ -14,7 +14,7 @@ import { getHasMigratableThemes, migrateThemesV2, } from '../../lib/theme/migrat
14
14
  import { hasFeature } from '../../lib/hasFeature.js';
15
15
  import { FEATURES } from '../../lib/constants.js';
16
16
  import { trackCommandMetadataUsage } from '../../lib/usageTracking.js';
17
- const { v2025_2, v2026_03_beta, v2026_03 } = PLATFORM_VERSIONS;
17
+ const { v2025_2, v2026_03_BETA, v2026_03 } = PLATFORM_VERSIONS;
18
18
  const command = 'migrate';
19
19
  const describe = commands.project.migrate.describe;
20
20
  async function handler(args) {
@@ -41,7 +41,7 @@ async function handler(args) {
41
41
  await migrateThemesV2(derivedAccountId, {
42
42
  ...args,
43
43
  platformVersion: unstable
44
- ? PLATFORM_VERSIONS.unstable
44
+ ? PLATFORM_VERSIONS.UNSTABLE
45
45
  : platformVersion,
46
46
  }, migratableThemesCount, projectConfig);
47
47
  }
@@ -50,7 +50,7 @@ async function handler(args) {
50
50
  ...args,
51
51
  name: projectConfig?.projectConfig?.name,
52
52
  platformVersion: unstable
53
- ? PLATFORM_VERSIONS.unstable
53
+ ? PLATFORM_VERSIONS.UNSTABLE
54
54
  : platformVersion,
55
55
  }, projectConfig);
56
56
  }
@@ -67,7 +67,7 @@ function projectMigrateBuilder(yargs) {
67
67
  yargs
68
68
  .option('platform-version', {
69
69
  type: 'string',
70
- choices: [v2025_2, v2026_03_beta, v2026_03],
70
+ choices: [v2025_2, v2026_03_BETA, v2026_03],
71
71
  default: v2026_03,
72
72
  })
73
73
  .option('unstable', {
@@ -3,7 +3,7 @@ import fs from 'fs';
3
3
  import { getConfigAccountIfExists, getAllConfigAccounts, } from '@hubspot/local-dev-lib/config';
4
4
  import { getAllHsProfiles, getHsProfileFilename, loadHsProfileFile, } from '@hubspot/project-parsing-lib/profiles';
5
5
  import { getProjectConfig } from '../../../lib/projects/config.js';
6
- import { isV2Project } from '../../../lib/projects/platformVersion.js';
6
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
7
7
  import { uiAccountDescription } from '../../../lib/ui/index.js';
8
8
  import { uiLogger } from '../../../lib/ui/logger.js';
9
9
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
@@ -57,7 +57,7 @@ async function handler(args) {
57
57
  uiLogger.error(commands.project.profile.add.errors.noProjectConfig);
58
58
  return exit(EXIT_CODES.ERROR);
59
59
  }
60
- if (!isV2Project(projectConfig.platformVersion)) {
60
+ if (isLegacyProject(projectConfig.platformVersion)) {
61
61
  uiLogger.error(commands.project.profile.add.errors.unsupportedPlatformVersion);
62
62
  return exit(EXIT_CODES.ERROR);
63
63
  }
@@ -4,7 +4,7 @@ import { getAllHsProfiles, getHsProfileFilename, loadHsProfileFile, } from '@hub
4
4
  import { fetchProject, deleteProject, } from '@hubspot/local-dev-lib/api/projects';
5
5
  import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
6
6
  import { getProjectConfig } from '../../../lib/projects/config.js';
7
- import { isV2Project } from '../../../lib/projects/platformVersion.js';
7
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
8
8
  import { uiLogger } from '../../../lib/ui/logger.js';
9
9
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
10
10
  import { makeYargsHandlerWithUsageTracking } from '../../../lib/yargs/makeYargsHandlerWithUsageTracking.js';
@@ -23,7 +23,7 @@ async function handler(args) {
23
23
  uiLogger.error(commands.project.profile.delete.errors.noProjectConfig);
24
24
  return exit(EXIT_CODES.ERROR);
25
25
  }
26
- if (!isV2Project(projectConfig.platformVersion)) {
26
+ if (isLegacyProject(projectConfig.platformVersion)) {
27
27
  uiLogger.error(commands.project.profile.delete.errors.unsupportedPlatformVersion);
28
28
  return exit(EXIT_CODES.ERROR);
29
29
  }
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import { uiLogger } from '../../lib/ui/logger.js';
3
3
  import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
4
4
  import { isSpecifiedError } from '@hubspot/local-dev-lib/errors/index';
5
- import { isV2Project } from '../../lib/projects/platformVersion.js';
5
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
6
6
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
7
7
  import { logFeedbackMessage } from '../../lib/projects/ui.js';
8
8
  import { handleProjectUpload } from '../../lib/projects/upload.js';
@@ -34,7 +34,7 @@ async function handler(args) {
34
34
  }
35
35
  let targetAccountId;
36
36
  let profileName = args.profile;
37
- if (isV2Project(projectConfig?.platformVersion)) {
37
+ if (!isLegacyProject(projectConfig?.platformVersion)) {
38
38
  try {
39
39
  const profileNamePromptResult = await projectProfilePrompt(projectDir, projectConfig, profileOption, !!useEnvOption);
40
40
  if (profileNamePromptResult) {
@@ -64,7 +64,7 @@ async function handler(args) {
64
64
  uploadMessage: message,
65
65
  forceCreate,
66
66
  isUploadCommand: true,
67
- sendIR: isV2Project(projectConfig.platformVersion),
67
+ sendIR: !isLegacyProject(projectConfig.platformVersion),
68
68
  skipValidation,
69
69
  profile: profileName,
70
70
  });
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
  import { getConfigAccountById } from '@hubspot/local-dev-lib/config';
3
- import { isV2Project } from '../../lib/projects/platformVersion.js';
3
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
4
4
  import { uiLogger } from '../../lib/ui/logger.js';
5
5
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
6
6
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
@@ -24,7 +24,7 @@ async function handler(args) {
24
24
  uiLogger.error(commands.project.validate.mustBeRanWithinAProject);
25
25
  return exit(EXIT_CODES.ERROR);
26
26
  }
27
- if (!isV2Project(projectConfig.platformVersion)) {
27
+ if (isLegacyProject(projectConfig.platformVersion)) {
28
28
  uiLogger.error(commands.project.validate.badVersion);
29
29
  return exit(EXIT_CODES.ERROR);
30
30
  }
@@ -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 { isV2Project } from '../../lib/projects/platformVersion.js';
3
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
4
4
  import { commands } from '../../lang/en.js';
5
5
  import { createWatcher } from '../../lib/projects/watch.js';
6
6
  import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
@@ -62,7 +62,7 @@ async function handler(args) {
62
62
  uiLogger.error(commands.project.watch.errors.projectConfigNotFound);
63
63
  return exit(EXIT_CODES.ERROR);
64
64
  }
65
- if (isV2Project(projectConfig.platformVersion)) {
65
+ if (!isLegacyProject(projectConfig.platformVersion)) {
66
66
  uiLogger.error(commands.project.watch.errors.v2ApiError(projectConfig.platformVersion));
67
67
  return exit(EXIT_CODES.ERROR);
68
68
  }
@@ -21,7 +21,7 @@ import info from './project/info.js';
21
21
  import deleteProject from './project/delete.js';
22
22
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
23
23
  import { getProjectConfig } from '../lib/projects/config.js';
24
- import { isUnsupportedPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '../lib/projects/platformVersion.js';
24
+ import { isSupportedPlatformVersion, LATEST_SUPPORTED_PLATFORM_VERSION, } from '@hubspot/project-parsing-lib/projects';
25
25
  import { uiLogger } from '../lib/ui/logger.js';
26
26
  import { debugError } from '../lib/errorHandlers/index.js';
27
27
  const command = ['project', 'projects'];
@@ -31,8 +31,11 @@ const describe = commands.project.describe;
31
31
  async function validatePlatformVersion() {
32
32
  try {
33
33
  const { projectConfig } = await getProjectConfig();
34
- if (isUnsupportedPlatformVersion(projectConfig?.platformVersion)) {
35
- uiLogger.warn(lib.projects.platformVersion.unsupported(pkg.version, LATEST_SUPPORTED_PLATFORM_VERSION, projectConfig?.platformVersion));
34
+ // Only warn if a platform version is explicitly set but not supported
35
+ // Don't warn if the platform version is missing/undefined
36
+ if (projectConfig?.platformVersion &&
37
+ !isSupportedPlatformVersion(projectConfig.platformVersion)) {
38
+ uiLogger.warn(lib.projects.platformVersion.unsupported(pkg.version, LATEST_SUPPORTED_PLATFORM_VERSION, projectConfig.platformVersion));
36
39
  uiLogger.log('');
37
40
  }
38
41
  }
@@ -44,14 +44,14 @@ function readConfigFile(configPath) {
44
44
  async function promptForConfigPath() {
45
45
  const createTestAccountFromConfig = await listPrompt(commands.testAccount.create.createTestAccountFromConfigPrompt, {
46
46
  choices: [
47
- {
48
- name: commands.testAccount.create.createFromConfigOption,
49
- value: true,
50
- },
51
47
  {
52
48
  name: commands.testAccount.create.createFromScratchOption,
53
49
  value: false,
54
50
  },
51
+ {
52
+ name: commands.testAccount.create.createFromConfigOption,
53
+ value: true,
54
+ },
55
55
  ],
56
56
  });
57
57
  if (createTestAccountFromConfig) {
package/lang/en.d.ts CHANGED
@@ -4036,6 +4036,7 @@ export declare const lib: {
4036
4036
  migrate: {
4037
4037
  componentsToBeMigrated: (components: string) => string;
4038
4038
  componentsThatWillNotBeMigrated: (components: string) => string;
4039
+ legacyCrmCardMigrationDocs: () => string;
4039
4040
  sourceContentsMoved: (newLocation: string) => string;
4040
4041
  projectMigrationWarningTitle: (platformVersion: string) => string;
4041
4042
  projectMigrationWarning: (platformVersion: string) => string;
package/lang/en.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import { mapToUserFriendlyName } from '@hubspot/project-parsing-lib/transform';
3
- import { PLATFORM_VERSIONS } from '@hubspot/local-dev-lib/constants/projects';
3
+ import { PLATFORM_VERSIONS } from '@hubspot/project-parsing-lib/constants';
4
4
  import { PERSONAL_ACCESS_KEY_AUTH_METHOD } from '@hubspot/local-dev-lib/constants/auth';
5
5
  import { ARCHIVED_HUBSPOT_CONFIG_YAML_FILE_NAME, GLOBAL_CONFIG_PATH, DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME, } from '@hubspot/local-dev-lib/constants/config';
6
6
  import { uiAccountDescription, uiBetaTag, uiCommandReference, uiLink, UI_COLORS, uiAuthCommandReference, } from '../lib/ui/index.js';
@@ -1321,7 +1321,7 @@ export const commands = {
1321
1321
  },
1322
1322
  },
1323
1323
  api: {
1324
- describe: 'Make an authenticated HTTP request to the HubSpot API.',
1324
+ describe: 'Make an authenticated HTTP request to any HubSpot API endpoint that supports PAKs.',
1325
1325
  verboseDescribe: `Make an authenticated HTTP request to any HubSpot API that supports PAKs using your CLI authentication.\n\nThis command is intended for testing and exploration of HubSpot APIs. It uses the authentication credentials configured in the CLI to make requests on your behalf.\n\nThe endpoint should be the API path, e.g. ${chalk.bold('/crm/v3/objects/contacts')}. The request will be authenticated using the account specified by ${uiCommandReference('--account')} or the default account.\n\nNote: The available endpoints depend on the scopes granted to your personal access key. If you receive a 403 error, check that your key includes the required scopes for the endpoint you are trying to reach. ${uiLink('Learn more about the HubSpot API', 'https://developers.hubspot.com/docs/api-reference/latest/overview')}`,
1326
1326
  positionals: {
1327
1327
  endpoint: {
@@ -2324,7 +2324,7 @@ export const commands = {
2324
2324
  configPathPrompt: '[--config-path] Enter the path to the test account config: ',
2325
2325
  createTestAccountFromConfigPrompt: 'How would you like to create your test account?',
2326
2326
  createFromConfigOption: 'Create test account from config file',
2327
- createFromScratchOption: 'Create test account from scratch',
2327
+ createFromScratchOption: 'Select hub tiers manually',
2328
2328
  errors: {
2329
2329
  configFileNotFound: (configPath) => `No test account config file exists at ${configPath}. Create a test account config file with the ${uiCommandReference('hs test-account create-config')} command.`,
2330
2330
  configFileParseFailed: (configPath) => `Failed to parse test account config file at ${configPath}`,
@@ -4056,6 +4056,7 @@ export const lib = {
4056
4056
  migrate: {
4057
4057
  componentsToBeMigrated: (components) => `${chalk.bold('The following features will be migrated:')} ${components}`,
4058
4058
  componentsThatWillNotBeMigrated: (components) => `[NOTE] These features are not yet supported for migration but will be available later: ${components}`,
4059
+ legacyCrmCardMigrationDocs: () => `For more information on migrating legacy-crm-card components, follow ${uiLink('these docs', 'https://developers.hubspot.com/docs/apps/developer-platform/build-apps/migrate-an-app/migrate-legacy-crm-cards-to-app-cards')}`,
4059
4060
  sourceContentsMoved: (newLocation) => `The contents of your old source directory have been moved to ${newLocation}, move any required files to the new source directory.`,
4060
4061
  projectMigrationWarningTitle: (platformVersion) => `Important: Migrating to platformVersion ${platformVersion} is irreversible`,
4061
4062
  projectMigrationWarning: (platformVersion) => uiBetaTag(`Running the ${uiCommandReference('hs project migrate')} command will permanently upgrade your project to platformVersion ${platformVersion}. This action cannot be undone. To ensure you have access to your original files, they will be copied to a new directory (archive) for safekeeping.\n\nThis command will guide you through the process, prompting you to enter the required fields and will download the new project source code into your project source directory.`, false),
@@ -4070,7 +4071,7 @@ export const lib = {
4070
4071
  doesNotExist: (account) => `Project does not exist in ${uiAccountDescription(account)}. Migrations are only supported for existing projects.`,
4071
4072
  themesAlreadyMigrated: 'This project has already been migrated to the latest platform version.',
4072
4073
  noProjectForThemesMigration: 'Theme migrations are only supported for projects. Please try again from a project directory.',
4073
- themesAndAppsNotAllowed: 'Support for migrating projects containing both themes and apps to the latest platform version is coming soon. Try again later.',
4074
+ themesAndAppsNotAllowed: 'Projects containing both themes and apps cannot be migrated together. To migrate, split the project into separate theme-only and app-only projects, then run migrate on each individually.',
4074
4075
  multipleApps: 'Multiple apps found in project, this is not allowed in 2025.2',
4075
4076
  alreadyExists: (projectName) => `A project with name ${projectName} already exists. Please choose another name.`,
4076
4077
  failedToMigrateThemes: 'Failed to migrate project themes. Please verify that your themes are properly formatted before trying again.',
@@ -124,8 +124,12 @@ export async function selectAppToMigrate(allApps, derivedAccountId, appId) {
124
124
  const selectedApp = allApps.find(app => app.appId === appIdToMigrate);
125
125
  const migratableComponents = new Set();
126
126
  const unmigratableComponents = new Set();
127
+ let hasLegacyCrmCards = false;
127
128
  selectedApp?.migrationComponents.forEach(component => {
128
129
  const userFacingComponentType = mapToUserFacingType(component.componentType);
130
+ if (component.componentType === 'LEGACY_CRM_CARD' && !component.isSupported) {
131
+ hasLegacyCrmCards = true;
132
+ }
129
133
  const shouldDisplayComponent = !AUTO_GENERATED_COMPONENT_TYPES.includes(userFacingComponentType);
130
134
  if (shouldDisplayComponent) {
131
135
  if (component.isSupported) {
@@ -142,6 +146,9 @@ export async function selectAppToMigrate(allApps, derivedAccountId, appId) {
142
146
  if (unmigratableComponents.size !== 0) {
143
147
  uiLogger.log(lib.migrate.componentsThatWillNotBeMigrated(`\n - ${[...unmigratableComponents].join('\n - ')}`));
144
148
  }
149
+ if (hasLegacyCrmCards) {
150
+ uiLogger.info(lib.migrate.legacyCrmCardMigrationDocs());
151
+ }
145
152
  uiLogger.log('');
146
153
  const proceed = await confirmPrompt(lib.migrate.prompt.proceed, {
147
154
  defaultAnswer: false,
@@ -26,7 +26,7 @@ import { isServerRunningAtUrl } from '../http.js';
26
26
  import { WEBHOOKS_KEY, APP_KEY } from '@hubspot/project-parsing-lib/constants';
27
27
  import { validateProjectConfig } from '../projects/config.js';
28
28
  import { validateSourceDirectory, handleTranslate, } from '../projects/upload.js';
29
- import { isV2Project } from '../projects/platformVersion.js';
29
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
30
30
  import { validateProjectForProfile } from '../projects/projectProfiles.js';
31
31
  import { getAllHsProfiles } from '@hubspot/project-parsing-lib/profiles';
32
32
  const minMajorNodeVersion = 20;
@@ -534,7 +534,7 @@ export class Doctor {
534
534
  if (!this.validateProjectConfigWrapper(projectConfig, projectDir)) {
535
535
  return;
536
536
  }
537
- if (!isV2Project(projectConfig.platformVersion)) {
537
+ if (isLegacyProject(projectConfig.platformVersion)) {
538
538
  this.diagnosis?.addProjectSection({
539
539
  type: 'success',
540
540
  message: lib.doctor.projectValidation.valid,
@@ -13,7 +13,7 @@ import { getStaticAuthAppInstallUrl } from '../lib/app/urls.js';
13
13
  import { HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, PROJECT_CONFIG_FILE, } from '../lib/constants.js';
14
14
  import { ProjectNestingError, ProjectConfigNotFoundError, ProjectValidationError, ProjectUploadError, ProjectBuildDeployError, } from './errors/ProjectErrors.js';
15
15
  import { getProjectConfig, validateProjectConfig, writeProjectConfig, } from '../lib/projects/config.js';
16
- import { isV2Project } from '../lib/projects/platformVersion.js';
16
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
17
17
  import { pollProjectBuildAndDeploy } from '../lib/projects/pollProjectBuildAndDeploy.js';
18
18
  import { handleProjectUpload } from '../lib/projects/upload.js';
19
19
  import { validateProjectDirectory } from '../lib/prompts/projectNameAndDestPrompt.js';
@@ -109,7 +109,7 @@ export async function uploadAndDeployAction({ accountId, projectDest, }) {
109
109
  uploadMessage: commands.getStarted.logs.initialUploadMessage,
110
110
  forceCreate: true,
111
111
  isUploadCommand: false,
112
- sendIR: isV2Project(projectConfig.platformVersion),
112
+ sendIR: !isLegacyProject(projectConfig.platformVersion),
113
113
  skipValidation: false,
114
114
  });
115
115
  if (uploadError) {
@@ -4,7 +4,7 @@ import { fetchProjectComponentsMetadata } from '@hubspot/local-dev-lib/api/proje
4
4
  import { fetchAppMetadataBySourceId } from '@hubspot/local-dev-lib/api/appsDev';
5
5
  import { uiLogger } from '../ui/logger.js';
6
6
  import { commands } from '../../lang/en.js';
7
- import { isV2Project } from './platformVersion.js';
7
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
8
8
  import { getDeployedProjectNodes } from './localDev/helpers/project.js';
9
9
  import { debugError } from '../errorHandlers/index.js';
10
10
  class _ProjectLogsManager {
@@ -51,7 +51,7 @@ class _ProjectLogsManager {
51
51
  throw new Error(commands.project.logs.errors.failedToFetchProjectDetails);
52
52
  }
53
53
  this.projectId = project.id;
54
- if (isV2Project(projectConfig.platformVersion)) {
54
+ if (!isLegacyProject(projectConfig.platformVersion)) {
55
55
  const deployedBuildId = project.deployedBuild.buildId;
56
56
  if (!deployedBuildId) {
57
57
  throw new Error(commands.project.logs.errors.noDeployedBuild);
@@ -1,7 +1,7 @@
1
1
  import { selectProjectTemplatePrompt, } from '../../prompts/selectProjectTemplatePrompt.js';
2
2
  import { projectNameAndDestPrompt } from '../../prompts/projectNameAndDestPrompt.js';
3
3
  import { DEFAULT_PROJECT_TEMPLATE_BRANCH, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, EMPTY_PROJECT, } from '../../constants.js';
4
- import { isV2Project } from '../platformVersion.js';
4
+ import { isLegacyProject } from '@hubspot/project-parsing-lib/projects';
5
5
  import { v2ComponentFlow } from './v2.js';
6
6
  import { getProjectTemplateListFromRepo } from './legacy.js';
7
7
  import { commands } from '../../../lang/en.js';
@@ -9,7 +9,7 @@ export async function handleProjectCreationFlow(args) {
9
9
  const { platformVersion, templateSource, projectBase, auth: providedAuth, distribution: providedDistribution, } = args;
10
10
  const repo = templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
11
11
  const projectNameAndDestPromptResponse = await projectNameAndDestPrompt(args);
12
- if (isV2Project(platformVersion)) {
12
+ if (!isLegacyProject(platformVersion)) {
13
13
  const { componentTemplateChoices, authType, distribution, repoConfig, projectContents, } = await v2ComponentFlow(platformVersion, projectBase, providedAuth, providedDistribution, args.derivedAccountId);
14
14
  const selectProjectTemplatePromptResponse = await selectProjectTemplatePrompt(args, undefined, projectContents !== EMPTY_PROJECT ? componentTemplateChoices : undefined);
15
15
  return {