@hubspot/cli 7.8.1-experimental.0 → 7.8.2-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
@@ -34,8 +34,8 @@ describe('commands/get-started', () => {
34
34
  });
35
35
  });
36
36
  describe('describe', () => {
37
- it('should have undefined describe property', () => {
38
- expect(getStartedCommand.describe).toBeUndefined();
37
+ it('should have a defined describe property', () => {
38
+ expect(getStartedCommand.describe).toBeDefined();
39
39
  });
40
40
  });
41
41
  describe('command structure', () => {
@@ -19,7 +19,7 @@ describe('commands/mcp', () => {
19
19
  });
20
20
  describe('describe', () => {
21
21
  it('should provide a description', () => {
22
- expect(mcpCommand.describe).toBeUndefined();
22
+ expect(mcpCommand.describe).toBeDefined();
23
23
  });
24
24
  });
25
25
  describe('builder', () => {
@@ -51,9 +51,6 @@ describe('commands/project', () => {
51
51
  });
52
52
  });
53
53
  describe('describe', () => {
54
- it('should contain the beta tag', () => {
55
- expect(projectCommand.describe).toContain('[BETA]');
56
- });
57
54
  it('should provide a description', () => {
58
55
  expect(projectCommand.describe).toBeDefined();
59
56
  });
@@ -103,7 +103,6 @@ describe('commands/app/migrate', () => {
103
103
  'platform-version': expect.objectContaining({
104
104
  type: 'string',
105
105
  default: '2025.2',
106
- hidden: true,
107
106
  }),
108
107
  }));
109
108
  });
@@ -6,13 +6,13 @@ import { i18n } from '../../lib/lang.js';
6
6
  import { ApiErrorContext, logError } from '../../lib/errorHandlers/index.js';
7
7
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
8
8
  import { migrateApp2025_2 } from '../../lib/app/migrate.js';
9
- import { uiBetaTag, uiCommandReference, uiLink } from '../../lib/ui/index.js';
9
+ import { uiCommandReference, uiLink } from '../../lib/ui/index.js';
10
10
  import { migrateApp2023_2 } from '../../lib/app/migrate_legacy.js';
11
11
  import { getIsInProject } from '../../lib/projects/config.js';
12
12
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
13
13
  const { v2023_2, v2025_2 } = PLATFORM_VERSIONS;
14
14
  const command = 'migrate';
15
- const describe = undefined; // uiBetaTag(i18n(`commands.project.subcommands.migrateApp.header.text.describe`), false);
15
+ const describe = i18n(`commands.project.subcommands.migrateApp.describe`);
16
16
  export function handlerGenerator(commandTrackingName) {
17
17
  return async function handler(args) {
18
18
  const { derivedAccountId, platformVersion, unstable } = args;
@@ -23,7 +23,7 @@ export function handlerGenerator(commandTrackingName) {
23
23
  return process.exit(EXIT_CODES.ERROR);
24
24
  }
25
25
  logger.log('');
26
- logger.log(uiBetaTag(i18n(`commands.project.subcommands.migrateApp.header.text`), false));
26
+ logger.log(i18n(`commands.project.subcommands.migrateApp.header.text`));
27
27
  logger.log(uiLink(i18n(`commands.project.subcommands.migrateApp.header.link`), 'https://developers.hubspot.com/docs/platform/migrate-a-public-app-to-projects'));
28
28
  logger.log('');
29
29
  try {
@@ -76,7 +76,6 @@ function appMigrateBuilder(yargs) {
76
76
  'platform-version': {
77
77
  type: 'string',
78
78
  choices: [v2023_2, v2025_2],
79
- hidden: true,
80
79
  default: v2025_2,
81
80
  },
82
81
  unstable: {
@@ -93,7 +92,7 @@ function appMigrateBuilder(yargs) {
93
92
  ]);
94
93
  return yargs;
95
94
  }
96
- const builder = makeYargsBuilder(appMigrateBuilder, command, uiBetaTag(i18n(`commands.project.subcommands.migrateApp.describe`), false), {
95
+ const builder = makeYargsBuilder(appMigrateBuilder, command, i18n(`commands.project.subcommands.migrateApp.describe`), {
97
96
  useGlobalOptions: true,
98
97
  useConfigOptions: true,
99
98
  useAccountOptions: true,
@@ -7,8 +7,9 @@ import { commands } from '../../../lang/en.js';
7
7
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
8
8
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
9
9
  import { uiLogger } from '../../../lib/ui/logger.js';
10
+ import { uiBetaTag } from '../../../lib/ui/index.js';
10
11
  const command = 'add [name]';
11
- const describe = commands.app.subcommands.secret.subcommands.add.describe;
12
+ const describe = uiBetaTag(commands.app.subcommands.secret.subcommands.add.describe, false);
12
13
  async function handler(args) {
13
14
  const { derivedAccountId } = args;
14
15
  trackCommandUsage('app-secret-add', {}, derivedAccountId);
@@ -7,8 +7,9 @@ import { commands } from '../../../lang/en.js';
7
7
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
8
8
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
9
9
  import { uiLogger } from '../../../lib/ui/logger.js';
10
+ import { uiBetaTag } from '../../../lib/ui/index.js';
10
11
  const command = 'delete [name]';
11
- const describe = commands.app.subcommands.secret.subcommands.delete.describe;
12
+ const describe = uiBetaTag(commands.app.subcommands.secret.subcommands.delete.describe, false);
12
13
  async function handler(args) {
13
14
  const { derivedAccountId, force } = args;
14
15
  trackCommandUsage('app-secret-delete', {}, derivedAccountId);
@@ -6,8 +6,9 @@ import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
6
6
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
7
7
  import { selectAppPrompt } from '../../../lib/prompts/selectAppPrompt.js';
8
8
  import { uiLogger } from '../../../lib/ui/logger.js';
9
+ import { uiBetaTag } from '../../../lib/ui/index.js';
9
10
  const command = 'list';
10
- const describe = commands.app.subcommands.secret.subcommands.list.describe;
11
+ const describe = uiBetaTag(commands.app.subcommands.secret.subcommands.list.describe, false);
11
12
  async function handler(args) {
12
13
  const { derivedAccountId } = args;
13
14
  trackCommandUsage('app-secret-list', {}, derivedAccountId);
@@ -8,8 +8,9 @@ import { commands } from '../../../lang/en.js';
8
8
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
9
9
  import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
10
10
  import { uiLogger } from '../../../lib/ui/logger.js';
11
+ import { uiBetaTag } from '../../../lib/ui/index.js';
11
12
  const command = 'update [name]';
12
- const describe = commands.app.subcommands.secret.subcommands.update.describe;
13
+ const describe = uiBetaTag(commands.app.subcommands.secret.subcommands.update.describe, false);
13
14
  async function handler(args) {
14
15
  const { derivedAccountId } = args;
15
16
  trackCommandUsage('app-secret-update', {}, derivedAccountId);
@@ -4,8 +4,9 @@ import addAppSecretCommand from './secret/add.js';
4
4
  import deleteAppSecretCommand from './secret/delete.js';
5
5
  import listAppSecretsCommand from './secret/list.js';
6
6
  import updateAppSecretCommand from './secret/update.js';
7
+ import { uiBetaTag } from '../../lib/ui/index.js';
7
8
  const command = ['secret', 'secrets'];
8
- const describe = undefined; // commands.app.subcommands.secret.describe;
9
+ const describe = uiBetaTag(commands.app.subcommands.secret.describe, false);
9
10
  function appSecretBuilder(yargs) {
10
11
  yargs
11
12
  .command(addAppSecretCommand)
package/commands/app.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import migrateCommand from './app/migrate.js';
2
2
  import appSecretCommand from './app/secret.js';
3
3
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
4
+ import { commands } from '../lang/en.js';
4
5
  const command = ['app', 'apps'];
5
- // Keep the command hidden for now
6
- const describe = undefined;
6
+ const describe = commands.app.describe;
7
7
  function appBuilder(yargs) {
8
8
  yargs.command(migrateCommand).command(appSecretCommand).demandCommand(1, '');
9
9
  return yargs;
@@ -84,7 +84,6 @@ function configSetBuilder(yargs) {
84
84
  'auto-open-browser': {
85
85
  describe: commands.config.subcommands.set.options.autoOpenBrowser.describe,
86
86
  type: 'boolean',
87
- hidden: true,
88
87
  },
89
88
  })
90
89
  .conflicts(getExclusiveConflicts([
@@ -5,7 +5,7 @@ import { confirmPrompt } from '../lib/prompts/promptUtils.js';
5
5
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
6
6
  import { EXIT_CODES } from '../lib/enums/exitCodes.js';
7
7
  import { uiLink } from '../lib/ui/index.js';
8
- const FEEDBACK_URL = 'https://developers.hubspot.com/feedback.js';
8
+ const FEEDBACK_URL = 'https://developers.hubspot.com/feedback';
9
9
  const command = 'feedback';
10
10
  const describe = i18n(`commands.project.subcommands.feedback.describe`);
11
11
  async function handler() {
@@ -1,6 +1,4 @@
1
1
  import { AccountArgs, YargsCommandModule, CommonArgs, ConfigArgs, EnvironmentArgs } from '../types/Yargs.js';
2
- export declare const command = "get-started";
3
- export declare const describe: undefined;
4
2
  type GetStartedArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & {
5
3
  name?: string;
6
4
  dest?: string;
@@ -23,8 +23,8 @@ import { getStaticAuthAppInstallUrl } from '../lib/app/urls.js';
23
23
  import { getEnv } from '@hubspot/local-dev-lib/config';
24
24
  import { ENVIRONMENTS } from '@hubspot/local-dev-lib/constants/environments';
25
25
  import { fetchPublicAppsForPortal } from '@hubspot/local-dev-lib/api/appsDev';
26
- export const command = 'get-started';
27
- export const describe = undefined;
26
+ const command = 'get-started';
27
+ const describe = commands.getStarted.describe;
28
28
  async function handler(args) {
29
29
  const { derivedAccountId } = args;
30
30
  const env = getEnv(derivedAccountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD;
@@ -3,12 +3,12 @@ vi.mock('../../../lib/commonOpts');
3
3
  describe('commands/mcp/setup', () => {
4
4
  describe('command', () => {
5
5
  it('should have the correct command structure', () => {
6
- expect(setupCommand.command).toEqual(['setup', 'update']);
6
+ expect(setupCommand.command).toEqual(['setup']);
7
7
  });
8
8
  });
9
9
  describe('describe', () => {
10
10
  it('should be undefined to keep the command hidden', () => {
11
- expect(setupCommand.describe).toBeUndefined();
11
+ expect(setupCommand.describe).toBeDefined();
12
12
  });
13
13
  });
14
14
  describe('builder', () => {
@@ -6,8 +6,9 @@ import { addMcpServerToConfig, supportedTools } from '../../lib/mcp/setup.js';
6
6
  import { trackCommandUsage } from '../../lib/usageTracking.js';
7
7
  import { hasFeature } from '../../lib/hasFeature.js';
8
8
  import { FEATURES } from '../../lib/constants.js';
9
- const command = ['setup', 'update'];
10
- const describe = undefined; // Leave hidden for now
9
+ import { uiBetaTag } from '../../lib/ui/index.js';
10
+ const command = ['setup'];
11
+ const describe = uiBetaTag(commands.mcp.setup.describe, false);
11
12
  async function handler(args) {
12
13
  const { derivedAccountId } = args;
13
14
  const hasMcpAccess = await hasFeature(derivedAccountId, FEATURES.MCP_ACCESS);
package/commands/mcp.js CHANGED
@@ -2,14 +2,14 @@ import startCommand from './mcp/start.js';
2
2
  import setupCommand from './mcp/setup.js';
3
3
  import { makeYargsBuilder } from '../lib/yargsUtils.js';
4
4
  import { commands } from '../lang/en.js';
5
+ import { uiBetaTag } from '../lib/ui/index.js';
5
6
  const command = 'mcp';
6
- // Leave this as undefined to hide the command
7
- const describe = undefined;
7
+ const describe = uiBetaTag(commands.mcp.describe, false);
8
8
  function mcpBuilder(yargs) {
9
9
  yargs.command(startCommand).command(setupCommand).demandCommand(1, '');
10
10
  return yargs;
11
11
  }
12
- const builder = makeYargsBuilder(mcpBuilder, command, commands.mcp.describe, {
12
+ const builder = makeYargsBuilder(mcpBuilder, command, describe, {
13
13
  useGlobalOptions: true,
14
14
  });
15
15
  const mcpCommand = {
@@ -48,10 +48,10 @@ describe('commands/project/create', () => {
48
48
  projectCreateCommand.builder(yargsMock);
49
49
  const optionsCall = optionsSpy.mock.calls[0][0];
50
50
  expect(optionsCall['platform-version']).toEqual(expect.objectContaining({
51
- hidden: true,
51
+ describe: 'The target platform version for the new project.',
52
52
  type: 'string',
53
53
  choices: ['2023.2', '2025.1', '2025.2'],
54
- default: '2023.2',
54
+ default: '2025.2',
55
55
  }));
56
56
  });
57
57
  it('should define project base option with correct choices', () => {
@@ -59,7 +59,7 @@ describe('commands/project/create', () => {
59
59
  projectCreateCommand.builder(yargsMock);
60
60
  const optionsCall = optionsSpy.mock.calls[0][0];
61
61
  expect(optionsCall['project-base']).toEqual(expect.objectContaining({
62
- hidden: true,
62
+ describe: 'The top level component to include in the project.',
63
63
  type: 'string',
64
64
  choices: ['empty', 'app'],
65
65
  }));
@@ -69,7 +69,7 @@ describe('commands/project/create', () => {
69
69
  projectCreateCommand.builder(yargsMock);
70
70
  const optionsCall = optionsSpy.mock.calls[0][0];
71
71
  expect(optionsCall.distribution).toEqual(expect.objectContaining({
72
- hidden: true,
72
+ describe: 'How the app will be distributed.',
73
73
  type: 'string',
74
74
  choices: ['private', 'marketplace'],
75
75
  }));
@@ -79,7 +79,7 @@ describe('commands/project/create', () => {
79
79
  projectCreateCommand.builder(yargsMock);
80
80
  const optionsCall = optionsSpy.mock.calls[0][0];
81
81
  expect(optionsCall.auth).toEqual(expect.objectContaining({
82
- hidden: true,
82
+ describe: 'Authentication model for the application.',
83
83
  type: 'string',
84
84
  choices: ['oauth', 'static'],
85
85
  }));
@@ -89,7 +89,7 @@ describe('commands/project/create', () => {
89
89
  projectCreateCommand.builder(yargsMock);
90
90
  const optionsCall = optionsSpy.mock.calls[0][0];
91
91
  expect(optionsCall.features).toEqual(expect.objectContaining({
92
- hidden: true,
92
+ describe: 'Features to include in the project. Only valid if project-base is app',
93
93
  type: 'array',
94
94
  }));
95
95
  });
@@ -62,9 +62,6 @@ describe('commands/project/deploy', () => {
62
62
  });
63
63
  });
64
64
  describe('describe', () => {
65
- it('should contain the beta tag', () => {
66
- expect(projectDeployCommand.describe).toContain('[BETA]');
67
- });
68
65
  it('should provide a description', () => {
69
66
  expect(projectDeployCommand.describe).toBeDefined();
70
67
  });
@@ -324,8 +324,7 @@ describe('unifiedProjectDevFlow', () => {
324
324
  });
325
325
  expect(createNewProjectForLocalDev).not.toHaveBeenCalled();
326
326
  expect(LocalDevProcess).toHaveBeenCalledWith(expect.objectContaining({
327
- projectId: mockProject.id,
328
- projectName: mockProject.name,
327
+ projectData: mockProject,
329
328
  }));
330
329
  });
331
330
  });
@@ -346,8 +345,7 @@ describe('unifiedProjectDevFlow', () => {
346
345
  targetTestingAccountId: mockProvidedTargetTestingAccountId,
347
346
  projectConfig: mockProjectConfig,
348
347
  projectDir: mockProjectDir,
349
- projectName: mockProject.name,
350
- projectId: mockProject.id,
348
+ projectData: mockProject,
351
349
  env: ENVIRONMENTS.PROD,
352
350
  });
353
351
  });
@@ -45,9 +45,6 @@ describe('commands/project/logs', () => {
45
45
  });
46
46
  });
47
47
  describe('describe', () => {
48
- it('should contain the beta tag', () => {
49
- expect(projectLogsCommand.describe).toContain('[BETA]');
50
- });
51
48
  it('should provide a description', () => {
52
49
  expect(projectLogsCommand.describe).toBeDefined();
53
50
  });
@@ -44,7 +44,7 @@ describe('commands/project/migrate', () => {
44
44
  });
45
45
  describe('describe', () => {
46
46
  it('should provide a description', () => {
47
- expect(migrateCommand.describe).toBe(undefined);
47
+ expect(migrateCommand.describe).toBeDefined();
48
48
  });
49
49
  });
50
50
  describe('builder', () => {
@@ -54,7 +54,6 @@ describe('commands/project/migrate', () => {
54
54
  type: 'string',
55
55
  choices: [v2025_2],
56
56
  default: v2025_2,
57
- hidden: true,
58
57
  });
59
58
  expect(optionsSpy).toHaveBeenCalledWith('unstable', {
60
59
  type: 'boolean',
@@ -57,8 +57,7 @@ describe('commands/project/migrateApp', () => {
57
57
  'platform-version': expect.objectContaining({
58
58
  type: 'string',
59
59
  choices: [v2023_2, v2025_2],
60
- hidden: true,
61
- default: v2023_2,
60
+ default: v2025_2,
62
61
  }),
63
62
  });
64
63
  expect(exampleSpy).toHaveBeenCalled();
@@ -19,7 +19,7 @@ describe('commands/project', () => {
19
19
  });
20
20
  describe('describe', () => {
21
21
  it('should not provide a description', () => {
22
- expect(profileCommand.describe).not.toBeDefined();
22
+ expect(profileCommand.describe).toBeDefined();
23
23
  });
24
24
  });
25
25
  describe('builder', () => {
@@ -1,6 +1,5 @@
1
1
  import { logError } from '../../lib/errorHandlers/index.js';
2
2
  import { getProjectConfig } from '../../lib/projects/config.js';
3
- import { uiBetaTag } from '../../lib/ui/index.js';
4
3
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
5
4
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
6
5
  import { commands } from '../../lang/en.js';
@@ -10,7 +9,7 @@ import { v3AddComponent } from '../../lib/projects/add/v3AddComponent.js';
10
9
  import { marketplaceDistribution, oAuth, privateDistribution, staticAuth, } from '../../lib/constants.js';
11
10
  import { uiLogger } from '../../lib/ui/logger.js';
12
11
  const command = 'add';
13
- const describe = uiBetaTag(commands.project.add.describe, false);
12
+ const describe = commands.project.add.describe;
14
13
  async function handler(args) {
15
14
  try {
16
15
  const { derivedAccountId } = args;
@@ -45,19 +44,16 @@ function projectAddBuilder(yargs) {
45
44
  },
46
45
  distribution: {
47
46
  describe: commands.project.add.options.distribution.describe,
48
- hidden: true,
49
47
  type: 'string',
50
48
  choices: [privateDistribution, marketplaceDistribution],
51
49
  },
52
50
  auth: {
53
51
  describe: commands.project.add.options.auth.describe,
54
- hidden: true,
55
52
  type: 'string',
56
53
  choices: [oAuth, staticAuth],
57
54
  },
58
55
  features: {
59
56
  describe: commands.project.add.options.features.describe,
60
- hidden: true,
61
57
  type: 'array',
62
58
  },
63
59
  });
@@ -7,7 +7,7 @@ import { writeProjectConfig, getProjectConfig, } from '../../lib/projects/config
7
7
  import { EMPTY_PROJECT_TEMPLATE_NAME } from '../../lib/projects/create/legacy.js';
8
8
  import { generateComponentPaths } from '../../lib/projects/create/v3.js';
9
9
  import { PROJECT_WITH_APP, EMPTY_PROJECT } from '../../lib/constants.js';
10
- import { uiBetaTag, uiFeatureHighlight } from '../../lib/ui/index.js';
10
+ import { uiFeatureHighlight } from '../../lib/ui/index.js';
11
11
  import { debugError, logError } from '../../lib/errorHandlers/index.js';
12
12
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
13
13
  import { PROJECT_CONFIG_FILE, HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, marketplaceDistribution, privateDistribution, oAuth, staticAuth, DEFAULT_PROJECT_TEMPLATE_BRANCH, } from '../../lib/constants.js';
@@ -19,7 +19,7 @@ import { handleProjectCreationFlow, } from '../../lib/projects/create/index.js';
19
19
  import { getProjectMetadata, } from '@hubspot/project-parsing-lib/src/lib/project.js';
20
20
  import { updateHsMetaFilesWithAutoGeneratedFields } from '../../lib/projects/components.js';
21
21
  const command = ['create', 'init'];
22
- const describe = uiBetaTag(commands.project.create.describe, false);
22
+ const describe = commands.project.create.describe;
23
23
  const { v2023_2, v2025_1, v2025_2 } = PLATFORM_VERSIONS;
24
24
  async function handler(args) {
25
25
  const { derivedAccountId, platformVersion, templateSource } = args;
@@ -112,7 +112,6 @@ function projectCreateBuilder(yargs) {
112
112
  type: 'string',
113
113
  },
114
114
  template: {
115
- // TODO: When we release 2025.2 scaffolding, we need to point out this is only valid for 2025.1 prior
116
115
  describe: commands.project.create.options.template.describe,
117
116
  type: 'string',
118
117
  },
@@ -122,32 +121,27 @@ function projectCreateBuilder(yargs) {
122
121
  },
123
122
  'platform-version': {
124
123
  describe: commands.project.create.options.platformVersion.describe,
125
- hidden: true,
126
124
  type: 'string',
127
125
  choices: [v2023_2, v2025_1, v2025_2],
128
- default: v2023_2,
126
+ default: v2025_2,
129
127
  },
130
128
  'project-base': {
131
129
  describe: commands.project.create.options.projectBase.describe,
132
- hidden: true,
133
130
  type: 'string',
134
131
  choices: [EMPTY_PROJECT, PROJECT_WITH_APP],
135
132
  },
136
133
  distribution: {
137
134
  describe: commands.project.create.options.distribution.describe,
138
- hidden: true,
139
135
  type: 'string',
140
136
  choices: [privateDistribution, marketplaceDistribution],
141
137
  },
142
138
  auth: {
143
139
  describe: commands.project.create.options.auth.describe,
144
- hidden: true,
145
140
  type: 'string',
146
141
  choices: [oAuth, staticAuth],
147
142
  },
148
143
  features: {
149
144
  describe: commands.project.create.options.features.describe,
150
- hidden: true,
151
145
  type: 'array',
152
146
  },
153
147
  });
@@ -7,7 +7,7 @@ import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
7
7
  import { getProjectConfig } from '../../lib/projects/config.js';
8
8
  import { projectNamePrompt } from '../../lib/prompts/projectNamePrompt.js';
9
9
  import { promptUser } from '../../lib/prompts/promptUtils.js';
10
- import { uiBetaTag, uiLine } from '../../lib/ui/index.js';
10
+ import { uiLine } from '../../lib/ui/index.js';
11
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
12
12
  import { uiLogger } from '../../lib/ui/logger.js';
13
13
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
@@ -16,7 +16,7 @@ import { PROJECT_DEPLOY_TEXT } from '../../lib/constants.js';
16
16
  import { commands } from '../../lang/en.js';
17
17
  import { handleProjectDeploy, validateBuildIdForDeploy, logDeployErrors, } from '../../lib/projects/deploy.js';
18
18
  const command = 'deploy';
19
- const describe = uiBetaTag(commands.project.deploy.describe, false);
19
+ const describe = commands.project.deploy.describe;
20
20
  async function handler(args) {
21
21
  const { derivedAccountId, project: projectOption, buildId: buildIdOption, force: forceOption, deployLatestBuild: deployLatestBuildOption, json: formatOutputAsJson, } = args;
22
22
  const accountConfig = getAccountConfig(derivedAccountId);
@@ -2,7 +2,7 @@ import { trackCommandUsage } from '../../../lib/usageTracking.js';
2
2
  import { getAccountId } from '@hubspot/local-dev-lib/config';
3
3
  import { getProjectConfig, validateProjectConfig, } from '../../../lib/projects/config.js';
4
4
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
5
- import { uiBetaTag, uiLine } from '../../../lib/ui/index.js';
5
+ import { uiLine } from '../../../lib/ui/index.js';
6
6
  import { deprecatedProjectDevFlow } from './deprecatedFlow.js';
7
7
  import { unifiedProjectDevFlow } from './unifiedFlow.js';
8
8
  import { useV3Api } from '../../../lib/projects/platformVersion.js';
@@ -10,8 +10,9 @@ import { makeYargsBuilder } from '../../../lib/yargsUtils.js';
10
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
+ import { logger } from '@hubspot/local-dev-lib/logger';
13
14
  const command = 'dev';
14
- const describe = uiBetaTag(commands.project.dev.describe, false);
15
+ const describe = commands.project.dev.describe;
15
16
  function validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV3) {
16
17
  // Legacy projects do not support targetTestingAccount and targetProjectAccount
17
18
  if (testingAccount && projectAccount && !useV3) {
@@ -33,7 +34,7 @@ async function handler(args) {
33
34
  process.exit(EXIT_CODES.ERROR);
34
35
  }
35
36
  validateAccountFlags(testingAccount, projectAccount, userProvidedAccount, useV3);
36
- uiBetaTag(commands.project.dev.logs.betaMessage);
37
+ logger.log(commands.project.dev.logs.header);
37
38
  if (useV3) {
38
39
  uiLogger.log(commands.project.dev.logs.learnMoreMessageV3);
39
40
  }
@@ -9,7 +9,7 @@ import { logError } from '../../../lib/errorHandlers/index.js';
9
9
  import { EXIT_CODES } from '../../../lib/enums/exitCodes.js';
10
10
  import { ensureProjectExists } from '../../../lib/projects/ensureProjectExists.js';
11
11
  import { createInitialBuildForNewProject, createNewProjectForLocalDev, compareLocalProjectToDeployed, } from '../../../lib/projects/localDev/helpers/project.js';
12
- import { useExistingDevTestAccount, createDeveloperTestAccountForLocalDev, selectAccountTypePrompt, } from '../../../lib/projects/localDev/helpers/account.js';
12
+ import { useExistingDevTestAccount, createDeveloperTestAccountForLocalDev, selectAccountTypePrompt, createSandboxForLocalDev, } from '../../../lib/projects/localDev/helpers/account.js';
13
13
  import { selectDeveloperTestTargetAccountPrompt, selectSandboxTargetAccountPrompt, } from '../../../lib/prompts/projectDevTargetAccountPrompt.js';
14
14
  import SpinniesManager from '../../../lib/ui/SpinniesManager.js';
15
15
  import LocalDevProcess from '../../../lib/projects/localDev/LocalDevProcess.js';
@@ -93,6 +93,9 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
93
93
  const sandboxAccountPromptResponse = await selectSandboxTargetAccountPrompt(accounts, targetProjectAccountConfig);
94
94
  targetTestingAccountId =
95
95
  sandboxAccountPromptResponse.targetAccountId || undefined;
96
+ if (sandboxAccountPromptResponse.createNestedAccount) {
97
+ targetTestingAccountId = await createSandboxForLocalDev(targetProjectAccountId, targetProjectAccountConfig, env);
98
+ }
96
99
  }
97
100
  else {
98
101
  targetTestingAccountId = targetProjectAccountId;
@@ -125,8 +128,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
125
128
  targetTestingAccountId: targetTestingAccountId,
126
129
  projectConfig,
127
130
  projectDir,
128
- projectName: project.name,
129
- projectId: project.id,
131
+ projectData: project,
130
132
  env,
131
133
  });
132
134
  await localDevProcess.start();
@@ -7,12 +7,11 @@ import { logError, ApiErrorContext } from '../../lib/errorHandlers/index.js';
7
7
  import { getProjectConfig } from '../../lib/projects/config.js';
8
8
  import { downloadProjectPrompt } from '../../lib/prompts/downloadProjectPrompt.js';
9
9
  import { i18n } from '../../lib/lang.js';
10
- import { uiBetaTag } from '../../lib/ui/index.js';
11
10
  import { trackCommandUsage } from '../../lib/usageTracking.js';
12
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
13
12
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
14
13
  const command = 'download';
15
- const describe = uiBetaTag(i18n(`commands.project.subcommands.download.describe`), false);
14
+ const describe = i18n(`commands.project.subcommands.download.describe`);
16
15
  async function handler(args) {
17
16
  const { projectConfig } = await getProjectConfig();
18
17
  if (projectConfig) {
@@ -6,11 +6,10 @@ import { promptUser } from '../../lib/prompts/promptUtils.js';
6
6
  import path from 'path';
7
7
  import { i18n } from '../../lib/lang.js';
8
8
  import { trackCommandUsage } from '../../lib/usageTracking.js';
9
- import { uiBetaTag } from '../../lib/ui/index.js';
10
9
  import { logError } from '../../lib/errorHandlers/index.js';
11
10
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
12
11
  const command = 'install-deps [packages..]';
13
- const describe = uiBetaTag(i18n(`commands.project.subcommands.installDeps.help.describe`), false);
12
+ const describe = i18n(`commands.project.subcommands.installDeps.help.describe`);
14
13
  async function handler(args) {
15
14
  const { derivedAccountId, packages } = args;
16
15
  try {
@@ -2,7 +2,7 @@ import { isHubSpotHttpError } from '@hubspot/local-dev-lib/errors/index';
2
2
  import { logger } from '@hubspot/local-dev-lib/logger';
3
3
  import { fetchProject, fetchProjectBuilds, } from '@hubspot/local-dev-lib/api/projects';
4
4
  import { getTableContents, getTableHeader } from '../../lib/ui/table.js';
5
- import { uiBetaTag, uiLink } from '../../lib/ui/index.js';
5
+ import { uiLink } from '../../lib/ui/index.js';
6
6
  import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
7
7
  import { getProjectDetailUrl } from '../../lib/projects/urls.js';
8
8
  import moment from 'moment';
@@ -14,7 +14,7 @@ import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
14
14
  import { makeYargsBuilder } from '../../lib/yargsUtils.js';
15
15
  import { commands } from '../../lang/en.js';
16
16
  const command = 'list-builds';
17
- const describe = uiBetaTag(i18n(`commands.project.subcommands.listBuilds.describe`), false);
17
+ const describe = i18n(`commands.project.subcommands.listBuilds.describe`);
18
18
  async function fetchAndDisplayBuilds(accountId, project, options) {
19
19
  const { data: { results, paging }, } = await fetchProjectBuilds(accountId, project.name, options);
20
20
  const currentDeploy = project.deployedBuildId;
@@ -5,7 +5,7 @@ import { logger } from '@hubspot/local-dev-lib/logger';
5
5
  import { trackCommandUsage } from '../../lib/usageTracking.js';
6
6
  import { getTableContents, getTableHeader } from '../../lib/ui/table.js';
7
7
  import { logError } from '../../lib/errorHandlers/index.js';
8
- import { uiBetaTag, uiLine, uiLink } from '../../lib/ui/index.js';
8
+ import { uiLine, uiLink } from '../../lib/ui/index.js';
9
9
  import { projectLogsPrompt } from '../../lib/prompts/projectsLogsPrompt.js';
10
10
  import { i18n } from '../../lib/lang.js';
11
11
  import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
@@ -43,7 +43,7 @@ function logPreamble() {
43
43
  uiLine();
44
44
  }
45
45
  const command = 'logs';
46
- const describe = uiBetaTag(i18n(`commands.project.subcommands.logs.describe`), false);
46
+ const describe = i18n(`commands.project.subcommands.logs.describe`);
47
47
  async function handler(args) {
48
48
  const { derivedAccountId } = args;
49
49
  trackCommandUsage('project-logs', undefined, derivedAccountId);