@hubspot/cli 7.7.15-experimental.0 → 7.7.16-experimental.1

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 (71) hide show
  1. package/bin/cli.js +4 -0
  2. package/bin/hs +1 -1
  3. package/commands/getStarted.d.ts +9 -0
  4. package/commands/getStarted.js +227 -0
  5. package/commands/init.js +6 -1
  6. package/commands/mcp/setup.d.ts +4 -10
  7. package/commands/mcp/setup.js +28 -220
  8. package/commands/mcp/start.d.ts +3 -9
  9. package/commands/mcp/start.js +18 -15
  10. package/commands/mcp.js +2 -1
  11. package/commands/project/deploy.d.ts +1 -0
  12. package/commands/project/deploy.js +29 -3
  13. package/commands/project/upload.d.ts +2 -2
  14. package/commands/project/upload.js +18 -23
  15. package/commands/project/validate.d.ts +6 -0
  16. package/commands/project/validate.js +82 -0
  17. package/commands/project.js +2 -0
  18. package/commands/testAccount/create.d.ts +6 -0
  19. package/commands/testAccount/create.js +110 -0
  20. package/commands/testAccount/createConfig.d.ts +10 -0
  21. package/commands/testAccount/createConfig.js +98 -0
  22. package/commands/testAccount/delete.d.ts +6 -0
  23. package/commands/testAccount/delete.js +48 -0
  24. package/commands/testAccount.d.ts +3 -0
  25. package/commands/testAccount.js +28 -0
  26. package/lang/en.d.ts +144 -29
  27. package/lang/en.js +144 -32
  28. package/lang/en.lyaml +9 -14
  29. package/lib/app/migrate.js +15 -3
  30. package/lib/commonOpts.d.ts +2 -0
  31. package/lib/commonOpts.js +21 -9
  32. package/lib/constants.d.ts +5 -0
  33. package/lib/constants.js +6 -1
  34. package/lib/doctor/Doctor.js +1 -1
  35. package/lib/errorHandlers/index.js +7 -0
  36. package/lib/mcp/setup.d.ts +21 -0
  37. package/lib/mcp/setup.js +218 -0
  38. package/lib/projectProfiles.d.ts +1 -0
  39. package/lib/projectProfiles.js +18 -0
  40. package/lib/projects/buildAndDeploy.js +1 -1
  41. package/lib/projects/localDev/AppDevModeInterface.d.ts +3 -0
  42. package/lib/projects/localDev/AppDevModeInterface.js +45 -16
  43. package/lib/projects/localDev/LocalDevManager.js +1 -1
  44. package/lib/projects/upload.d.ts +3 -0
  45. package/lib/projects/upload.js +56 -22
  46. package/lib/projects/urls.d.ts +2 -0
  47. package/lib/projects/urls.js +10 -0
  48. package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +17 -0
  49. package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +96 -0
  50. package/lib/prompts/installAppPrompt.d.ts +2 -1
  51. package/lib/prompts/installAppPrompt.js +12 -2
  52. package/lib/prompts/promptUtils.d.ts +1 -0
  53. package/lib/prompts/promptUtils.js +2 -0
  54. package/lib/ui/logger.d.ts +1 -0
  55. package/lib/ui/logger.js +1 -0
  56. package/lib/yargsUtils.d.ts +1 -0
  57. package/lib/yargsUtils.js +3 -0
  58. package/mcp-server/tools/index.js +2 -0
  59. package/mcp-server/tools/project/AddFeatureToProject.js +6 -29
  60. package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
  61. package/mcp-server/tools/project/CreateProjectTool.js +12 -31
  62. package/mcp-server/tools/project/DeployProject.js +4 -11
  63. package/mcp-server/tools/project/GuidedWalkthroughTool.js +3 -16
  64. package/mcp-server/tools/project/UploadProjectTools.js +3 -7
  65. package/mcp-server/tools/project/ValidateProjectTool.d.ts +17 -0
  66. package/mcp-server/tools/project/ValidateProjectTool.js +35 -0
  67. package/mcp-server/utils/content.d.ts +3 -0
  68. package/mcp-server/utils/content.js +21 -0
  69. package/package.json +10 -9
  70. package/types/LocalDev.d.ts +1 -0
  71. package/types/Yargs.d.ts +4 -0
package/lang/en.d.ts CHANGED
@@ -8,6 +8,54 @@ export declare const commands: {
8
8
  readonly configFileExists: (configPath: string) => string;
9
9
  };
10
10
  };
11
+ readonly getStarted: {
12
+ readonly options: {
13
+ readonly dest: {
14
+ readonly describe: "Directory where the project should be created";
15
+ };
16
+ readonly name: {
17
+ readonly describe: "Project name (cannot be changed)";
18
+ };
19
+ readonly templateSource: {
20
+ readonly describe: "Path to custom GitHub repository from which to create project template";
21
+ };
22
+ };
23
+ readonly startTitle: "Welcome to HubSpot Development!";
24
+ readonly verboseDescribe: "A step-by-step command to get you started with a HubSpot project.";
25
+ readonly startDescription: "You can use the HubSpot CLI to build apps, CMS themes, and more.";
26
+ readonly designManager: "To onboard with CMS, please visit the HubSpot Design Manager in your account and follow the checklist items.";
27
+ readonly openDesignManager: "Click here to go to the HubSpot Design Manager";
28
+ readonly openDesignManagerPrompt: "Open Design Manager in your browser?";
29
+ readonly openedDesignManager: "Redirected to Design Manager!";
30
+ readonly developerOverviewBrowserOpenPrep: "We'll take you to your HubSpot account and walk you through installing and previewing your new app.";
31
+ readonly openDeveloperOverviewPrompt: "Open HubSpot to go to your account?";
32
+ readonly openedDeveloperOverview: "HubSpot opened!";
33
+ readonly prompts: {
34
+ readonly selectOption: "Are you looking to build apps or CMS?";
35
+ readonly options: {
36
+ readonly app: "App";
37
+ readonly cms: "CMS";
38
+ };
39
+ readonly uploadProject: "Would you like to upload your project to HubSpot now?";
40
+ readonly appSelected: `We'll create a new project with a sample app for you.
41
+ Projects are what you can use to create apps, themes, and more at HubSpot.
42
+ Usually you'll use the ${string} command, but we'll go ahead and make one now.`;
43
+ readonly projectCreated: {
44
+ readonly title: string;
45
+ readonly description: `Upload your project to HubSpot - typically, you'll use the command ${string} for this.
46
+ We'll start the process now.`;
47
+ };
48
+ };
49
+ readonly logs: {
50
+ readonly uploadingProject: "Uploading your project to HubSpot...";
51
+ readonly uploadSuccess: "Project uploaded successfully!";
52
+ readonly developerOverviewLink: "Open this link to navigate to your HubSpot developer portal";
53
+ };
54
+ readonly errors: {
55
+ readonly uploadFailed: "Failed to upload project to HubSpot.";
56
+ readonly configFileNotFound: "Could not find project configuration for upload.";
57
+ };
58
+ };
11
59
  readonly completion: {
12
60
  readonly describe: "Enable bash completion shortcuts for commands. Concat the generated script to your .bashrc, .bash_profile, or .zshrc file.";
13
61
  readonly examples: {
@@ -765,6 +813,7 @@ Global configuration replaces hubspot.config.yml, and you will be prompted to mi
765
813
  readonly tailLogs: (functionPath: string, accountId: string) => string;
766
814
  };
767
815
  readonly mcp: {
816
+ readonly describe: "Commands for managing HubSpot MCP servers";
768
817
  readonly setup: {
769
818
  readonly installingDocSearch: "Adding the docs-search mcp server";
770
819
  readonly claudeCode: "Claude Code";
@@ -789,13 +838,11 @@ Global configuration replaces hubspot.config.yml, and you will be prompted to mi
789
838
  readonly claudeCodeInstallFailed: "Claude Code CLI not working - skipping configuration";
790
839
  readonly failedToConfigureClaudeDesktop: "Failed to configure Claude Desktop";
791
840
  readonly configuringCursor: "Configuring Cursor...";
792
- readonly noCursorMcpFile: (configFile: string) => string;
793
841
  readonly failedToConfigureCursor: "Failed to configure Cursor";
794
842
  readonly configuredCursor: "Configured Cursor";
795
843
  readonly alreadyInstalled: "HubSpot CLI mcp server already installed, reinstalling";
796
- readonly configuringWindsurf: "Configuring Cursor...";
797
- readonly noWindsurfFile: (configFile: string) => string;
798
- readonly failedToConfigureWindsurf: "Failed to configure Cursor";
844
+ readonly configuringWindsurf: "Configuring Windsurf...";
845
+ readonly failedToConfigureWindsurf: "Failed to configure Windsurf";
799
846
  readonly configuredWindsurf: "Configured Windsurf";
800
847
  };
801
848
  readonly prompts: {
@@ -1320,6 +1367,20 @@ ${string}`;
1320
1367
  readonly noPackageJsonInProject: (projectName: string, link: string) => string;
1321
1368
  readonly packageManagerNotInstalled: (packageManager: string, link: string) => string;
1322
1369
  };
1370
+ readonly validate: {
1371
+ readonly describe: "Validate the project before uploading";
1372
+ readonly mustBeRanWithinAProject: "This command must be run from within a project directory.";
1373
+ readonly badVersion: "This command is only available for projects 2025.2 and later.";
1374
+ readonly examples: {
1375
+ readonly default: "Validate the project before uploading";
1376
+ };
1377
+ readonly success: (projectName: string) => string;
1378
+ readonly options: {
1379
+ readonly profile: {
1380
+ readonly describe: "The profile to target for this validation";
1381
+ };
1382
+ };
1383
+ };
1323
1384
  };
1324
1385
  readonly remove: {
1325
1386
  readonly describe: "Delete a file or folder from the HubSpot CMS.";
@@ -1724,6 +1785,62 @@ ${string}`;
1724
1785
  readonly missingSrc: "Please specify the path to your javascript fields file or directory with the --src flag.";
1725
1786
  };
1726
1787
  };
1788
+ readonly testAccount: {
1789
+ readonly describe: "Commands for working with test accounts.";
1790
+ readonly create: {
1791
+ readonly describe: "Create a test account from a config file";
1792
+ readonly configPathPrompt: "[--config-path] Enter the path to the test account config: ";
1793
+ readonly createTestAccountFromConfigPrompt: "How would you like to create your test account?";
1794
+ readonly createFromConfigOption: "Create test account from config file";
1795
+ readonly createFromScratchOption: "Create test account from scratch";
1796
+ readonly errors: {
1797
+ readonly configFileNotFound: (configPath: string) => string;
1798
+ readonly configFileParseFailed: (configPath: string) => string;
1799
+ readonly failedToCreate: "Failed to create test account";
1800
+ };
1801
+ readonly success: {
1802
+ readonly configFileUpdated: (testAccountName: string, testAccountId: number) => string;
1803
+ };
1804
+ readonly options: {
1805
+ readonly configPath: "The path to the test account config";
1806
+ };
1807
+ readonly example: (configPath: string) => string;
1808
+ };
1809
+ readonly createConfig: {
1810
+ readonly describe: "Create a test account config file.";
1811
+ readonly pathPrompt: "[--path] What is the path to the test account config?";
1812
+ readonly errors: {
1813
+ readonly pathError: "Path is required";
1814
+ readonly pathFormatError: "Path must end with .json";
1815
+ readonly failedToCreate: "Failed to create test account config";
1816
+ readonly pathExistsError: "A file already exists at this path. Please try again with a different path.";
1817
+ };
1818
+ readonly success: {
1819
+ readonly configFileCreated: (path: string) => string;
1820
+ };
1821
+ readonly options: {
1822
+ readonly name: "The name of the test account";
1823
+ readonly description: "The description of the test account";
1824
+ readonly tiers: "The tiers of the test account";
1825
+ readonly path: "The path to the test account config";
1826
+ };
1827
+ readonly example: (name: string) => string;
1828
+ };
1829
+ readonly delete: {
1830
+ readonly describe: "Delete a test account config file.";
1831
+ readonly pathPrompt: "[--path] What is the path to the test account config?";
1832
+ readonly errors: {
1833
+ readonly failedToDelete: "Failed to delete test account";
1834
+ };
1835
+ readonly success: {
1836
+ readonly testAccountDeleted: (testAccountId: number) => string;
1837
+ };
1838
+ readonly positionals: {
1839
+ readonly testAccountId: "The id of the test account";
1840
+ };
1841
+ readonly example: (testAccountId: number) => string;
1842
+ };
1843
+ };
1727
1844
  readonly secrets: {
1728
1845
  readonly add: {
1729
1846
  readonly loading: {
@@ -2318,7 +2435,6 @@ export declare const lib: {
2318
2435
  readonly noCompatibleComponents: (serverKey: string) => string;
2319
2436
  };
2320
2437
  readonly LocalDevManager: {
2321
- readonly staticAuthAccountsMustMatch: "You must test static auth apps in the account the project exists in";
2322
2438
  readonly appNotFound: (accountId: number, appUid: string | undefined) => string;
2323
2439
  readonly failedToInitialize: "Missing required arguments to initialize Local Dev";
2324
2440
  readonly noDeployedBuild: (projectName: string, accountIdentifier: string, uploadCommand: string) => string;
@@ -2363,6 +2479,9 @@ export declare const lib: {
2363
2479
  };
2364
2480
  readonly AppDevModeInterface: {
2365
2481
  readonly defaultMarketplaceAppWarning: (installCount: number) => string;
2482
+ readonly autoInstallDeclined: "You must install your app on your target test account to proceed with local development.";
2483
+ readonly autoInstallSuccess: (appName: string, targetTestAccountId: number) => string;
2484
+ readonly autoInstallError: (appName: string, targetTestAccountId: number) => string;
2366
2485
  };
2367
2486
  readonly LocalDevWebsocketServer: {
2368
2487
  readonly errors: {
@@ -2514,7 +2633,7 @@ Run ${string} to upgrade to version ${string}`;
2514
2633
  readonly pollProjectBuildAndDeploy: {
2515
2634
  readonly buildSucceededAutomaticallyDeploying: (buildId: number, accountIdentifier: string) => string;
2516
2635
  readonly cleanedUpTempFile: (path: string) => string;
2517
- readonly viewDeploys: "View all deploys for this project in HubSpot";
2636
+ readonly viewDeploys: "view all deploys for this project in HubSpot";
2518
2637
  readonly unableToFindAutodeployStatus: (buildId: number, viewDeploysLink: string) => string;
2519
2638
  };
2520
2639
  };
@@ -2651,31 +2770,18 @@ Run ${string} to upgrade to version ${string}`;
2651
2770
  };
2652
2771
  readonly commonOpts: {
2653
2772
  readonly options: {
2654
- readonly account: {
2655
- readonly describe: "HubSpot account id or name from config";
2656
- };
2657
- readonly config: {
2658
- readonly describe: "Path to a config file";
2659
- };
2660
- readonly overwrite: {
2661
- readonly describe: "Overwrite existing files";
2662
- };
2773
+ readonly account: "HubSpot account id or name from config";
2774
+ readonly config: "Path to a config file";
2775
+ readonly overwrite: "Overwrite existing files";
2663
2776
  readonly modes: {
2664
- readonly describe: {
2665
- readonly default: (modes: string) => string;
2666
- readonly read: (modes: string) => string;
2667
- readonly write: (modes: string) => string;
2668
- };
2669
- };
2670
- readonly qa: {
2671
- readonly describe: "Run command in QA mode";
2672
- };
2673
- readonly useEnv: {
2674
- readonly describe: "Use environment variable config";
2675
- };
2676
- readonly debug: {
2677
- readonly describe: "Set log level to debug";
2777
+ readonly default: (modes: string) => string;
2778
+ readonly read: (modes: string) => string;
2779
+ readonly write: (modes: string) => string;
2678
2780
  };
2781
+ readonly qa: "Run command in QA mode";
2782
+ readonly useEnv: "Use environment variable config";
2783
+ readonly jsonOutput: "Format output as JSON";
2784
+ readonly debug: "Set log level to debug";
2679
2785
  };
2680
2786
  };
2681
2787
  readonly configMigrate: {
@@ -2717,6 +2823,14 @@ Run ${string} to upgrade to version ${string}`;
2717
2823
  readonly setAsDefaultAccount: (accountName: string) => string;
2718
2824
  readonly keepingCurrentDefault: (accountName: string) => string;
2719
2825
  };
2826
+ readonly createDeveloperTestAccountConfigPrompt: {
2827
+ readonly namePrompt: "[--name] What is the name of the test account?";
2828
+ readonly descriptionPrompt: "[--description] What is the description of the test account?";
2829
+ readonly tiersPrompt: "[--tiers] Which product tiers should the test account have?";
2830
+ readonly errors: {
2831
+ readonly tiersError: "Cannot have more than one tier per hub";
2832
+ };
2833
+ };
2720
2834
  readonly accountNamePrompt: {
2721
2835
  readonly enterAccountName: "Enter a unique name to reference this account in the CLI:";
2722
2836
  readonly enterDeveloperTestAccountName: "Name your developer test account:";
@@ -2889,6 +3003,7 @@ Run ${string} to upgrade to version ${string}`;
2889
3003
  readonly explanation: "Local development requires this app to be installed in the target test account";
2890
3004
  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.";
2891
3005
  readonly prompt: "Open HubSpot to install this app?";
3006
+ readonly autoPrompt: "Install this app in your target test account?";
2892
3007
  readonly reinstallPrompt: "Open HubSpot to reinstall this app?";
2893
3008
  readonly decline: `To continue local development of this app, install it in your target test account and re-run ${string}`;
2894
3009
  };
package/lang/en.js CHANGED
@@ -22,6 +22,51 @@ exports.commands = {
22
22
  configFileExists: (configPath) => `A configuration file already exists at ${configPath}. To specify a new configuration file, delete the existing one and try again.`,
23
23
  },
24
24
  },
25
+ getStarted: {
26
+ options: {
27
+ dest: {
28
+ describe: 'Directory where the project should be created',
29
+ },
30
+ name: {
31
+ describe: 'Project name (cannot be changed)',
32
+ },
33
+ templateSource: {
34
+ describe: 'Path to custom GitHub repository from which to create project template',
35
+ },
36
+ },
37
+ startTitle: 'Welcome to HubSpot Development!',
38
+ verboseDescribe: 'A step-by-step command to get you started with a HubSpot project.',
39
+ startDescription: 'You can use the HubSpot CLI to build apps, CMS themes, and more.',
40
+ designManager: 'To onboard with CMS, please visit the HubSpot Design Manager in your account and follow the checklist items.',
41
+ openDesignManager: 'Click here to go to the HubSpot Design Manager',
42
+ openDesignManagerPrompt: 'Open Design Manager in your browser?',
43
+ openedDesignManager: 'Redirected to Design Manager!',
44
+ developerOverviewBrowserOpenPrep: "We'll take you to your HubSpot account and walk you through installing and previewing your new app.",
45
+ openDeveloperOverviewPrompt: 'Open HubSpot to go to your account?',
46
+ openedDeveloperOverview: 'HubSpot opened!',
47
+ prompts: {
48
+ selectOption: 'Are you looking to build apps or CMS?',
49
+ options: {
50
+ app: 'App',
51
+ cms: 'CMS',
52
+ },
53
+ uploadProject: 'Would you like to upload your project to HubSpot now?',
54
+ appSelected: `We'll create a new project with a sample app for you.\nProjects are what you can use to create apps, themes, and more at HubSpot.\nUsually you'll use the ${(0, ui_1.uiCommandReference)('hs project create')} command, but we'll go ahead and make one now.`,
55
+ projectCreated: {
56
+ title: chalk_1.default.bold('Next steps:'),
57
+ description: `Upload your project to HubSpot - typically, you'll use the command ${(0, ui_1.uiCommandReference)('hs project upload')} for this.\nWe'll start the process now.`,
58
+ },
59
+ },
60
+ logs: {
61
+ uploadingProject: 'Uploading your project to HubSpot...',
62
+ uploadSuccess: 'Project uploaded successfully!',
63
+ developerOverviewLink: 'Open this link to navigate to your HubSpot developer portal',
64
+ },
65
+ errors: {
66
+ uploadFailed: 'Failed to upload project to HubSpot.',
67
+ configFileNotFound: 'Could not find project configuration for upload.',
68
+ },
69
+ },
25
70
  completion: {
26
71
  describe: 'Enable bash completion shortcuts for commands. Concat the generated script to your .bashrc, .bash_profile, or .zshrc file.',
27
72
  examples: {
@@ -777,6 +822,7 @@ exports.commands = {
777
822
  tailLogs: (functionPath, accountId) => `Waiting for log entries for "${functionPath}" on account "${accountId}".\n`,
778
823
  },
779
824
  mcp: {
825
+ describe: 'Commands for managing HubSpot MCP servers',
780
826
  setup: {
781
827
  installingDocSearch: 'Adding the docs-search mcp server',
782
828
  claudeCode: 'Claude Code',
@@ -787,7 +833,7 @@ exports.commands = {
787
833
  client: 'Target applications to configure',
788
834
  docsSearch: 'Should the docs search mcp server be installed',
789
835
  },
790
- success: (derivedTargets) => `You can now use the HubSpot CLI tools in ${derivedTargets.join(', ')}. ${chalk_1.default.bold('You may need to restart these tools to apply the changes')}.`,
836
+ success: (derivedTargets) => `You can now use the HubSpot CLI MCP Server in ${derivedTargets.join(', ')}. ${chalk_1.default.bold('You may need to restart these tools to apply the changes')}.`,
791
837
  errors: {
792
838
  needsNode20: `This feature requires node >=20`,
793
839
  },
@@ -801,13 +847,11 @@ exports.commands = {
801
847
  claudeCodeInstallFailed: 'Claude Code CLI not working - skipping configuration',
802
848
  failedToConfigureClaudeDesktop: 'Failed to configure Claude Desktop',
803
849
  configuringCursor: 'Configuring Cursor...',
804
- noCursorMcpFile: (configFile) => `No ${configFile} file found - skipping Cursor configuration`,
805
850
  failedToConfigureCursor: 'Failed to configure Cursor',
806
851
  configuredCursor: 'Configured Cursor',
807
852
  alreadyInstalled: 'HubSpot CLI mcp server already installed, reinstalling',
808
- configuringWindsurf: 'Configuring Cursor...',
809
- noWindsurfFile: (configFile) => `No ${configFile} file found - skipping Windsurf configuration`,
810
- failedToConfigureWindsurf: 'Failed to configure Cursor',
853
+ configuringWindsurf: 'Configuring Windsurf...',
854
+ failedToConfigureWindsurf: 'Failed to configure Windsurf',
811
855
  configuredWindsurf: 'Configured Windsurf',
812
856
  },
813
857
  prompts: {
@@ -1321,6 +1365,20 @@ exports.commands = {
1321
1365
  noPackageJsonInProject: (projectName, link) => `No dependencies to install. The project ${projectName} folder might be missing component or subcomponent files. ${link}`,
1322
1366
  packageManagerNotInstalled: (packageManager, link) => `This command depends on ${packageManager}, install ${chalk_1.default.bold(link)}`,
1323
1367
  },
1368
+ validate: {
1369
+ describe: 'Validate the project before uploading',
1370
+ mustBeRanWithinAProject: 'This command must be run from within a project directory.',
1371
+ badVersion: 'This command is only available for projects 2025.2 and later.',
1372
+ examples: {
1373
+ default: 'Validate the project before uploading',
1374
+ },
1375
+ success: (projectName) => `Project ${projectName} is valid and ready to upload`,
1376
+ options: {
1377
+ profile: {
1378
+ describe: 'The profile to target for this validation',
1379
+ },
1380
+ },
1381
+ },
1324
1382
  },
1325
1383
  remove: {
1326
1384
  describe: 'Delete a file or folder from the HubSpot CMS.',
@@ -1725,6 +1783,62 @@ exports.commands = {
1725
1783
  missingSrc: 'Please specify the path to your javascript fields file or directory with the --src flag.',
1726
1784
  },
1727
1785
  },
1786
+ testAccount: {
1787
+ describe: 'Commands for working with test accounts.',
1788
+ create: {
1789
+ describe: 'Create a test account from a config file',
1790
+ configPathPrompt: '[--config-path] Enter the path to the test account config: ',
1791
+ createTestAccountFromConfigPrompt: 'How would you like to create your test account?',
1792
+ createFromConfigOption: 'Create test account from config file',
1793
+ createFromScratchOption: 'Create test account from scratch',
1794
+ errors: {
1795
+ configFileNotFound: (configPath) => `No test account config file exists at ${configPath}. Create a test account config file with the ${(0, ui_1.uiCommandReference)('hs test-account create-config')} command.`,
1796
+ configFileParseFailed: (configPath) => `Failed to parse test account config file at ${configPath}`,
1797
+ failedToCreate: 'Failed to create test account',
1798
+ },
1799
+ success: {
1800
+ configFileUpdated: (testAccountName, testAccountId) => `Test account "${testAccountName}" successfully created with id ${testAccountId}`,
1801
+ },
1802
+ options: {
1803
+ configPath: 'The path to the test account config',
1804
+ },
1805
+ example: (configPath) => `Create a test account from the config file at ${configPath}`,
1806
+ },
1807
+ createConfig: {
1808
+ describe: 'Create a test account config file.',
1809
+ pathPrompt: '[--path] What is the path to the test account config?',
1810
+ errors: {
1811
+ pathError: 'Path is required',
1812
+ pathFormatError: 'Path must end with .json',
1813
+ failedToCreate: 'Failed to create test account config',
1814
+ pathExistsError: 'A file already exists at this path. Please try again with a different path.',
1815
+ },
1816
+ success: {
1817
+ configFileCreated: (path) => `Test account config successfully created at ${path}`,
1818
+ },
1819
+ options: {
1820
+ name: 'The name of the test account',
1821
+ description: 'The description of the test account',
1822
+ tiers: 'The tiers of the test account',
1823
+ path: 'The path to the test account config',
1824
+ },
1825
+ example: (name) => `Create a test account config file with the name "${name}"`,
1826
+ },
1827
+ delete: {
1828
+ describe: 'Delete a test account config file.',
1829
+ pathPrompt: '[--path] What is the path to the test account config?',
1830
+ errors: {
1831
+ failedToDelete: 'Failed to delete test account',
1832
+ },
1833
+ success: {
1834
+ testAccountDeleted: (testAccountId) => `Test account with id ${testAccountId} successfully deleted`,
1835
+ },
1836
+ positionals: {
1837
+ testAccountId: 'The id of the test account',
1838
+ },
1839
+ example: (testAccountId) => `Delete a test account with the id "${testAccountId}"`,
1840
+ },
1841
+ },
1728
1842
  secrets: {
1729
1843
  add: {
1730
1844
  loading: {
@@ -2319,7 +2433,6 @@ exports.lib = {
2319
2433
  noCompatibleComponents: (serverKey) => `Skipping call to ${serverKey} because there are no compatible components in the project.`,
2320
2434
  },
2321
2435
  LocalDevManager: {
2322
- staticAuthAccountsMustMatch: 'You must test static auth apps in the account the project exists in',
2323
2436
  appNotFound: (accountId, appUid) => `Unable to find app with uid ${appUid} in account ${(0, ui_1.uiAccountDescription)(accountId)}`,
2324
2437
  failedToInitialize: 'Missing required arguments to initialize Local Dev',
2325
2438
  noDeployedBuild: (projectName, accountIdentifier, uploadCommand) => `Your project ${chalk_1.default.bold(projectName)} exists in ${accountIdentifier}, but has no deployed build. Projects must be successfully deployed to be developed locally. Address any build and deploy errors your project may have, then run ${uploadCommand} to upload and deploy your project.`,
@@ -2364,6 +2477,9 @@ exports.lib = {
2364
2477
  },
2365
2478
  AppDevModeInterface: {
2366
2479
  defaultMarketplaceAppWarning: (installCount) => `\n\nYour marketplace app is currently installed in ${chalk_1.default.bold(`${installCount} ${installCount === 1 ? 'account' : 'accounts'}`)}. Any uploaded changes will impact your app's users. We strongly recommend creating a copy of this app to test your changes before proceding.`,
2480
+ autoInstallDeclined: 'You must install your app on your target test account to proceed with local development.',
2481
+ autoInstallSuccess: (appName, targetTestAccountId) => `Successfully installed app ${appName} on account ${(0, ui_1.uiAccountDescription)(targetTestAccountId)}\n`,
2482
+ autoInstallError: (appName, targetTestAccountId) => `Error installing app ${appName} on account ${(0, ui_1.uiAccountDescription)(targetTestAccountId)}. You may still be able to install your app in your browser.`,
2367
2483
  },
2368
2484
  LocalDevWebsocketServer: {
2369
2485
  errors: {
@@ -2512,8 +2628,8 @@ exports.lib = {
2512
2628
  pollProjectBuildAndDeploy: {
2513
2629
  buildSucceededAutomaticallyDeploying: (buildId, accountIdentifier) => `Build #${buildId} succeeded. ${chalk_1.default.bold('Automatically deploying')} to ${accountIdentifier}\n`,
2514
2630
  cleanedUpTempFile: (path) => `Cleaned up temporary file ${path}`,
2515
- viewDeploys: 'View all deploys for this project in HubSpot',
2516
- unableToFindAutodeployStatus: (buildId, viewDeploysLink) => `Unable to find the auto deploy for build #${buildId}. This deploy may have been skipped. ${viewDeploysLink}.`,
2631
+ viewDeploys: 'view all deploys for this project in HubSpot',
2632
+ unableToFindAutodeployStatus: (buildId, viewDeploysLink) => `Unable to find the auto deploy for build #${buildId}. This deploy may have been skipped or blocked due to components being removed. Manually deploy with ${(0, ui_1.uiCommandReference)('hs project deploy')} or ${viewDeploysLink}.`,
2517
2633
  },
2518
2634
  },
2519
2635
  projectUpload: {
@@ -2593,7 +2709,7 @@ exports.lib = {
2593
2709
  },
2594
2710
  projectDevCommand: {
2595
2711
  command: 'hs project dev',
2596
- message: (command) => `Run ${command} to set up your test environment and start local development`,
2712
+ message: (command) => `Run ${command} from within your project directory to set up your test environment and start local development`,
2597
2713
  },
2598
2714
  projectInstallDepsCommand: {
2599
2715
  command: 'hs project install-deps',
@@ -2649,31 +2765,18 @@ exports.lib = {
2649
2765
  },
2650
2766
  commonOpts: {
2651
2767
  options: {
2652
- account: {
2653
- describe: 'HubSpot account id or name from config',
2654
- },
2655
- config: {
2656
- describe: 'Path to a config file',
2657
- },
2658
- overwrite: {
2659
- describe: 'Overwrite existing files',
2660
- },
2768
+ account: 'HubSpot account id or name from config',
2769
+ config: 'Path to a config file',
2770
+ overwrite: 'Overwrite existing files',
2661
2771
  modes: {
2662
- describe: {
2663
- default: (modes) => `${modes}`,
2664
- read: (modes) => `Read from ${modes}`,
2665
- write: (modes) => `Write to ${modes}`,
2666
- },
2667
- },
2668
- qa: {
2669
- describe: 'Run command in QA mode',
2670
- },
2671
- useEnv: {
2672
- describe: 'Use environment variable config',
2673
- },
2674
- debug: {
2675
- describe: 'Set log level to debug',
2772
+ default: (modes) => `${modes}`,
2773
+ read: (modes) => `Read from ${modes}`,
2774
+ write: (modes) => `Write to ${modes}`,
2676
2775
  },
2776
+ qa: 'Run command in QA mode',
2777
+ useEnv: 'Use environment variable config',
2778
+ jsonOutput: 'Format output as JSON',
2779
+ debug: 'Set log level to debug',
2677
2780
  },
2678
2781
  },
2679
2782
  configMigrate: {
@@ -2715,6 +2818,14 @@ exports.lib = {
2715
2818
  setAsDefaultAccount: (accountName) => `Account "${accountName}" set as the default account`,
2716
2819
  keepingCurrentDefault: (accountName) => `Account "${accountName}" will continue to be the default account`,
2717
2820
  },
2821
+ createDeveloperTestAccountConfigPrompt: {
2822
+ namePrompt: '[--name] What is the name of the test account?',
2823
+ descriptionPrompt: '[--description] What is the description of the test account?',
2824
+ tiersPrompt: '[--tiers] Which product tiers should the test account have?',
2825
+ errors: {
2826
+ tiersError: 'Cannot have more than one tier per hub',
2827
+ },
2828
+ },
2718
2829
  accountNamePrompt: {
2719
2830
  enterAccountName: 'Enter a unique name to reference this account in the CLI:',
2720
2831
  enterDeveloperTestAccountName: 'Name your developer test account:',
@@ -2887,6 +2998,7 @@ exports.lib = {
2887
2998
  explanation: 'Local development requires this app to be installed in the target test account',
2888
2999
  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.",
2889
3000
  prompt: 'Open HubSpot to install this app?',
3001
+ autoPrompt: 'Install this app in your target test account?',
2890
3002
  reinstallPrompt: 'Open HubSpot to reinstall this app?',
2891
3003
  decline: `To continue local development of this app, install it in your target test account and re-run ${chalk_1.default.bold('`hs project dev`')}`,
2892
3004
  },
package/lang/en.lyaml CHANGED
@@ -694,6 +694,7 @@ en:
694
694
  buildIdDoesNotExist: "Build {{ buildId }} does not exist for project {{ projectName }}. {{ linkToProject }}"
695
695
  buildAlreadyDeployed: "Build {{ buildId }} is already deployed. {{ linkToProject}}"
696
696
  viewProjectsBuilds: 'View project builds in HubSpot'
697
+ deployContainsRemovals: "- This deploy would remove the {{#bold}}{{ componentName }}{{/bold}} component. To proceed, run the deploy command with the {{ forceFlag }} flag"
697
698
  examples:
698
699
  default: "Deploy the latest build of the current project"
699
700
  withOptions: "Deploy build 5 of the project my-project"
@@ -704,6 +705,8 @@ en:
704
705
  describe: "Project name"
705
706
  profile:
706
707
  describe: "The profile to target with this deploy"
708
+ force:
709
+ describe: "Skip warnings and force deploy. Use this carefully as it will bypass warnings for destructive actions."
707
710
  listBuilds:
708
711
  describe: "List the project's builds."
709
712
  continueOrExitPrompt: "Press <enter> to load more, or ctrl+c to exit"
@@ -1049,19 +1052,6 @@ en:
1049
1052
  logFeedbackMessage:
1050
1053
  feedbackHeader: "We'd love to hear your feedback!"
1051
1054
  feedbackMessage: "How are you liking the new projects and developer tools? \n > Run `{{#yellow}}hs feedback{{/yellow}}` to let us know what you think!\n"
1052
- projectBuildAndDeploy:
1053
- makePollTaskStatusFunc:
1054
- componentCountSingular: "Found 1 component in this project"
1055
- componentCount: "Found {{ numComponents }} components in this project"
1056
- successStatusText: "DONE"
1057
- failedStatusText: "FAILED"
1058
- errorFetchingTaskStatus: "An error occurred while fetching the status of the current {{ taskType }}. For more information, view this project in HubSpot by running {{ openCommand }}."
1059
- pollBuildAutodeployStatusError: "Error fetching autodeploy status for build #{{ buildId }}"
1060
- pollProjectBuildAndDeploy:
1061
- buildSucceededAutomaticallyDeploying: "Build #{{ buildId }} succeeded. {{#bold}}Automatically deploying{{/bold}} to {{ accountIdentifier }}\n"
1062
- cleanedUpTempFile: "Cleaned up temporary file {{ path }}"
1063
- viewDeploys: "View all deploys for this project in HubSpot"
1064
- unableToFindAutodeployStatus: "Unable to find the auto deploy for build #{{ buildId }}. This deploy may have been skipped. {{ viewDeploysLink }}."
1065
1055
  projectUpload:
1066
1056
  uploadProjectFiles:
1067
1057
  add: "Uploading {{#bold}}{{ projectName }}{{/bold}} project files to {{ accountIdentifier }}"
@@ -1107,6 +1097,9 @@ en:
1107
1097
  feedbackCommand:
1108
1098
  command: "hs feedback"
1109
1099
  message: "Run {{ command }} to report a bug or leave feedback"
1100
+ getStartedCommand:
1101
+ command: "hs get-started"
1102
+ message: "Run {{ command }} to get started with HubSpot development"
1110
1103
  helpCommand:
1111
1104
  command: "hs help"
1112
1105
  message: "Run {{ command }} to see a list of available commands"
@@ -1124,7 +1117,7 @@ en:
1124
1117
  message: "Run {{ command }} to upload your project to your HubSpot account"
1125
1118
  projectDevCommand:
1126
1119
  command: "hs project dev"
1127
- message: "Run {{ command }} to set up your test environment and start local development"
1120
+ message: "Run {{ command }} from within your project directory to set up your test environment and start local development"
1128
1121
  projectInstallDepsCommand:
1129
1122
  command: "hs project install-deps"
1130
1123
  message: "Run {{ command }} to install dependencies for your project components"
@@ -1165,6 +1158,8 @@ en:
1165
1158
  describe: "Use environment variable config"
1166
1159
  debug:
1167
1160
  describe: "Set log level to debug"
1161
+ jsonOutput:
1162
+ describe: "Format output as JSON"
1168
1163
  prompts:
1169
1164
  projectDevTargetAccountPrompt:
1170
1165
  createNewSandboxOption: "<Test on a new development sandbox>"
@@ -236,9 +236,21 @@ async function beginMigration(derivedAccountId, appId, platformVersion) {
236
236
  if (Object.values(componentsRequiringUids).length !== 0) {
237
237
  for (const [componentId, component] of Object.entries(componentsRequiringUids)) {
238
238
  const { componentHint, componentType } = component;
239
- uidMap[componentId] = await (0, promptUtils_1.inputPrompt)(en_1.lib.migrate.prompt.uidForComponent(componentHint
240
- ? `${(0, transform_1.mapToUserFacingType)(componentType)} '${componentHint}'`
241
- : (0, transform_1.mapToUserFacingType)(componentType)), {
239
+ // Extract the internal ID from the base64-encoded ComponentExternalId
240
+ let internalId;
241
+ try {
242
+ const decoded = Buffer.from(componentId, 'base64').toString('utf8');
243
+ const parts = decoded.split('$$');
244
+ internalId = parts[1] || componentId;
245
+ }
246
+ catch {
247
+ // If decoding fails, use the componentId as the internalId
248
+ internalId = componentId;
249
+ }
250
+ const promptText = componentHint
251
+ ? `${(0, transform_1.mapToUserFacingType)(componentType)} '${componentHint}' (ID: ${internalId})`
252
+ : `${(0, transform_1.mapToUserFacingType)(componentType)} (ID: ${internalId})`;
253
+ uidMap[componentId] = await (0, promptUtils_1.inputPrompt)(en_1.lib.migrate.prompt.uidForComponent(promptText), {
242
254
  validate: (uid) => {
243
255
  const result = (0, project_parsing_lib_1.validateUid)(uid);
244
256
  return result === undefined ? true : result;
@@ -11,10 +11,12 @@ export declare function addCmsPublishModeOptions(yargs: Argv, { read, write }: {
11
11
  }): Argv;
12
12
  export declare function addTestingOptions(yargs: Argv): Argv;
13
13
  export declare function addUseEnvironmentOptions(yargs: Argv): Argv;
14
+ export declare function addJSONOutputOptions(yargs: Argv): Argv;
14
15
  export declare function addCustomHelpOutput(yargs: Argv, command: string | string[], describe?: string): Promise<void>;
15
16
  export declare function setLogLevel(options: Arguments<{
16
17
  debug?: boolean;
17
18
  networkDebug?: boolean;
19
+ json?: boolean;
18
20
  }>): void;
19
21
  export declare function getCommandName(argv: Arguments): string;
20
22
  export declare function getCmsPublishMode(options: Arguments<{