@hubspot/cli 8.9.1 → 8.10.0-beta.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 (53) hide show
  1. package/commands/account/auth.js +2 -0
  2. package/commands/app/logs.js +4 -0
  3. package/commands/getStarted.js +3 -0
  4. package/commands/init.js +2 -0
  5. package/commands/mcp/setup.js +2 -2
  6. package/commands/project/appInstallStatus.js +2 -2
  7. package/commands/project/create.js +2 -0
  8. package/commands/project/dev/unifiedFlow.js +3 -1
  9. package/commands/project/installApp.d.ts +7 -0
  10. package/commands/project/installApp.js +181 -0
  11. package/commands/project/installDeps.js +2 -0
  12. package/commands/project/upload.d.ts +2 -0
  13. package/commands/project/upload.js +26 -5
  14. package/commands/project.js +2 -0
  15. package/commands/upgrade.js +2 -0
  16. package/lang/en.d.ts +66 -0
  17. package/lang/en.js +73 -7
  18. package/lib/accountTargetDiscovery.d.ts +15 -0
  19. package/lib/accountTargetDiscovery.js +175 -0
  20. package/lib/app/install.d.ts +22 -0
  21. package/lib/app/install.js +42 -0
  22. package/lib/app/logs.js +1 -1
  23. package/lib/auth/awaitPersonalAccessKeyOverWebsocket.js +3 -2
  24. package/lib/doctor/Doctor.d.ts +1 -0
  25. package/lib/doctor/Doctor.js +26 -0
  26. package/lib/getStartedV2Actions.js +2 -1
  27. package/lib/mcp/clients.d.ts +13 -0
  28. package/lib/mcp/clients.js +55 -0
  29. package/lib/mcp/promotion.d.ts +3 -0
  30. package/lib/mcp/promotion.js +109 -0
  31. package/lib/mcp/setup.d.ts +3 -2
  32. package/lib/mcp/setup.js +17 -12
  33. package/lib/projects/installApp.d.ts +58 -0
  34. package/lib/projects/installApp.js +283 -0
  35. package/lib/projects/localDev/AppDevModeInterface.d.ts +0 -3
  36. package/lib/projects/localDev/AppDevModeInterface.js +22 -44
  37. package/lib/projects/localDev/LocalDevProcess.js +4 -2
  38. package/lib/projects/localDev/helpers/project.js +3 -2
  39. package/lib/projects/ui.d.ts +1 -0
  40. package/lib/projects/ui.js +14 -0
  41. package/lib/projects/upload.d.ts +10 -2
  42. package/lib/projects/upload.js +15 -4
  43. package/lib/prompts/projectDevTargetAccountPrompt.js +3 -2
  44. package/lib/theme/cmsDevServerProcess.js +1 -1
  45. package/lib/usageTracking.d.ts +1 -0
  46. package/lib/usageTracking.js +9 -0
  47. package/mcp-server/tools/project/CreateTestAccountTool.js +1 -1
  48. package/mcp-server/tools/project/UploadProjectTools.js +1 -1
  49. package/package.json +5 -5
  50. package/types/AccountTargets.d.ts +37 -0
  51. package/types/AccountTargets.js +12 -0
  52. package/types/LocalDev.d.ts +3 -2
  53. package/types/ProjectComponents.d.ts +2 -1
@@ -95,8 +95,8 @@ class LocalDevProcess {
95
95
  });
96
96
  return true;
97
97
  }
98
- getIntermediateRepresentation(projectNodesAtLastDeploy) {
99
- return translateForLocalDev({
98
+ async getIntermediateRepresentation(projectNodesAtLastDeploy) {
99
+ const { intermediateRepresentation } = await translateForLocalDev({
100
100
  projectSourceDir: path.join(this.state.projectDir, this.state.projectConfig.srcDir),
101
101
  platformVersion: this.state.projectConfig.platformVersion,
102
102
  accountId: this.state.targetProjectAccountId,
@@ -104,6 +104,7 @@ class LocalDevProcess {
104
104
  projectNodesAtLastUpload: projectNodesAtLastDeploy,
105
105
  profile: this.state.profile,
106
106
  });
107
+ return intermediateRepresentation;
107
108
  }
108
109
  async updateProjectNodes() {
109
110
  const intermediateRepresentation = await this.getIntermediateRepresentation(this.state.projectNodesAtLastDeploy);
@@ -197,6 +198,7 @@ class LocalDevProcess {
197
198
  projectDir: this.state.projectDir,
198
199
  callbackFunc: pollProjectBuildAndDeploy,
199
200
  sendIR: true,
201
+ force: true,
200
202
  });
201
203
  const deploy = result?.deployResult;
202
204
  if (uploadError) {
@@ -85,6 +85,7 @@ export async function createInitialBuildForNewProject(projectConfig, projectDir,
85
85
  skipValidation: true,
86
86
  sendIR,
87
87
  profile,
88
+ force: true,
88
89
  });
89
90
  if (uploadError) {
90
91
  if (isSpecifiedError(uploadError, {
@@ -173,12 +174,12 @@ export async function getDeployedProjectNodes(projectConfig, accountId, deployed
173
174
  }
174
175
  }
175
176
  const deployedProjectSourceDir = path.join(tempDir, deployedSrcDir);
176
- const { intermediateNodesIndexedByUid } = await translate({
177
+ const { intermediateRepresentation } = await translate({
177
178
  projectSourceDir: deployedProjectSourceDir,
178
179
  platformVersion: projectConfig.platformVersion,
179
180
  accountId: accountId,
180
181
  }, { profile });
181
- return intermediateNodesIndexedByUid;
182
+ return intermediateRepresentation.intermediateNodesIndexedByUid;
182
183
  }
183
184
  finally {
184
185
  if (tempDir && (await fs.pathExists(tempDir))) {
@@ -1 +1,2 @@
1
1
  export declare function logFeedbackMessage(buildId: number): void;
2
+ export declare function warnAboutSkippedHsMetaFiles(skippedHsMetaFiles: string[], force: boolean, isUpload?: boolean): Promise<boolean>;
@@ -2,6 +2,7 @@ import { uiLogger } from '../ui/logger.js';
2
2
  import { FEEDBACK_INTERVAL } from '../constants.js';
3
3
  import { uiLine } from '../ui/index.js';
4
4
  import { lib } from '../../lang/en.js';
5
+ import { confirmPrompt } from '../prompts/promptUtils.js';
5
6
  export function logFeedbackMessage(buildId) {
6
7
  if (buildId > 0 && buildId % FEEDBACK_INTERVAL === 0) {
7
8
  uiLine();
@@ -10,3 +11,16 @@ export function logFeedbackMessage(buildId) {
10
11
  uiLogger.log(lib.projects.logFeedbackMessage.feedbackMessage);
11
12
  }
12
13
  }
14
+ export async function warnAboutSkippedHsMetaFiles(skippedHsMetaFiles, force, isUpload = true) {
15
+ if (skippedHsMetaFiles.length === 0)
16
+ return true;
17
+ const message = isUpload
18
+ ? lib.projects.skippedHsMetaFiles.uploadWarning(skippedHsMetaFiles)
19
+ : lib.projects.skippedHsMetaFiles.warning(skippedHsMetaFiles);
20
+ uiLogger.warn(message);
21
+ if (force)
22
+ return true;
23
+ return confirmPrompt(lib.projects.skippedHsMetaFiles.prompt, {
24
+ defaultAnswer: false,
25
+ });
26
+ }
@@ -1,4 +1,5 @@
1
1
  import { FileResult } from 'tmp';
2
+ import { type IntermediateRepresentation } from '@hubspot/project-parsing-lib/translate';
2
3
  import { ProjectConfig } from '../../types/Projects.js';
3
4
  type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId: number) => Promise<T>;
4
5
  type ProjectUploadResult<T> = {
@@ -6,6 +7,7 @@ type ProjectUploadResult<T> = {
6
7
  uploadError?: unknown;
7
8
  projectNotFound?: boolean;
8
9
  projectId?: number;
10
+ userDeclined?: boolean;
9
11
  };
10
12
  type HandleProjectUploadArg<T> = {
11
13
  accountId: number;
@@ -18,9 +20,11 @@ type HandleProjectUploadArg<T> = {
18
20
  sendIR?: boolean;
19
21
  skipValidation?: boolean;
20
22
  skipNpmAudit?: boolean;
23
+ skipAutoDeploy?: boolean;
21
24
  profile?: string;
25
+ force?: boolean;
22
26
  };
23
- export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, skipNpmAudit, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
27
+ export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, skipNpmAudit, skipAutoDeploy: _skipAutoDeploy, force, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
24
28
  export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig, projectDir: string): Promise<void>;
25
29
  export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
26
30
  type HandleTranslateArg = {
@@ -31,5 +35,9 @@ type HandleTranslateArg = {
31
35
  profile?: string;
32
36
  includeTranslationErrorMessage?: boolean;
33
37
  };
34
- export declare function handleTranslate({ projectDir, projectConfig, accountId, skipValidation, profile, includeTranslationErrorMessage, }: HandleTranslateArg): Promise<unknown>;
38
+ export type HandleTranslateResult = {
39
+ intermediateRepresentation: IntermediateRepresentation;
40
+ skippedHsMetaFiles: string[];
41
+ };
42
+ export declare function handleTranslate({ projectDir, projectConfig, accountId, skipValidation, profile, includeTranslationErrorMessage, }: HandleTranslateArg): Promise<HandleTranslateResult>;
35
43
  export {};
@@ -9,6 +9,7 @@ import { projectContainsHsMetaFiles } from '@hubspot/project-parsing-lib/project
9
9
  import { findAndParsePackageJsonFiles, collectWorkspaceDirectories, collectFileDependencies, } from '@hubspot/project-parsing-lib/workspaces';
10
10
  import SpinniesManager from '../ui/SpinniesManager.js';
11
11
  import { uiAccountDescription } from '../ui/index.js';
12
+ import { warnAboutSkippedHsMetaFiles } from './ui.js';
12
13
  import util from 'node:util';
13
14
  import { lib } from '../../lang/en.js';
14
15
  import { ensureProjectExists } from './ensureProjectExists.js';
@@ -29,6 +30,7 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
29
30
  let buildId;
30
31
  let error;
31
32
  try {
33
+ // TODO(skip-auto-deploy): Pass skipAutoDeploy once local-dev-lib is bumped
32
34
  const { data: upload } = await uploadProject(accountId, projectName, filePath, uploadMessage, platformVersion, intermediateRepresentation);
33
35
  buildId = upload.buildId;
34
36
  SpinniesManager.succeed('upload', {
@@ -46,7 +48,10 @@ async function uploadProjectFiles(accountId, projectName, filePath, uploadMessag
46
48
  }
47
49
  return { buildId, error };
48
50
  }
49
- export async function handleProjectUpload({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage = '', forceCreate = false, isUploadCommand = false, sendIR = false, skipValidation = false, skipNpmAudit = false, }) {
51
+ // TODO(skip-auto-deploy): Use skipAutoDeploy once local-dev-lib is bumped to support it
52
+ export async function handleProjectUpload({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage = '', forceCreate = false, isUploadCommand = false, sendIR = false, skipValidation = false, skipNpmAudit = false,
53
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
54
+ skipAutoDeploy: _skipAutoDeploy = false, force = false, }) {
50
55
  const srcDir = path.resolve(projectDir, projectConfig.srcDir);
51
56
  await validateSourceDirectory(srcDir, projectConfig, projectDir);
52
57
  await validateNoHSMetaMismatch(srcDir, projectConfig);
@@ -86,13 +91,19 @@ export async function handleProjectUpload({ accountId, projectConfig, projectDir
86
91
  let intermediateRepresentation;
87
92
  if (sendIR) {
88
93
  try {
89
- intermediateRepresentation = await handleTranslate({
94
+ const translateResult = await handleTranslate({
90
95
  projectDir,
91
96
  projectConfig,
92
97
  accountId,
93
98
  skipValidation,
94
99
  profile,
95
100
  });
101
+ intermediateRepresentation =
102
+ translateResult.intermediateRepresentation;
103
+ const shouldContinue = await warnAboutSkippedHsMetaFiles(translateResult.skippedHsMetaFiles, force);
104
+ if (!shouldContinue) {
105
+ return resolve({ userDeclined: true });
106
+ }
96
107
  }
97
108
  catch (e) {
98
109
  return resolve({ uploadError: e });
@@ -169,13 +180,13 @@ export async function validateNoHSMetaMismatch(srcDir, projectConfig) {
169
180
  }
170
181
  export async function handleTranslate({ projectDir, projectConfig, accountId, skipValidation, profile, includeTranslationErrorMessage = true, }) {
171
182
  try {
172
- const intermediateRepresentation = await translate({
183
+ const { intermediateRepresentation, skippedHsMetaFiles } = await translate({
173
184
  projectSourceDir: path.join(projectDir, projectConfig.srcDir),
174
185
  platformVersion: projectConfig.platformVersion,
175
186
  accountId,
176
187
  }, { skipValidation, profile });
177
188
  uiLogger.debug(util.inspect(intermediateRepresentation, false, null, true));
178
- return intermediateRepresentation;
189
+ return { intermediateRepresentation, skippedHsMetaFiles };
179
190
  }
180
191
  catch (e) {
181
192
  if (isTranslationError(e)) {
@@ -1,5 +1,5 @@
1
1
  import { getSandboxUsageLimits } from '@hubspot/local-dev-lib/api/sandboxHubs';
2
- import { HUBSPOT_ACCOUNT_TYPES, HUBSPOT_ACCOUNT_TYPE_STRINGS, } from '@hubspot/local-dev-lib/constants/config';
2
+ import { HUBSPOT_ACCOUNT_TYPE_STRINGS, HUBSPOT_ACCOUNT_TYPES, } from '@hubspot/local-dev-lib/constants/config';
3
3
  import { fetchDeveloperTestAccounts } from '@hubspot/local-dev-lib/api/developerTestAccounts';
4
4
  import { promptUser } from './promptUtils.js';
5
5
  import { lib } from '../../lang/en.js';
@@ -92,7 +92,8 @@ export async function selectDeveloperTestTargetAccountPrompt(accounts, defaultAc
92
92
  devTestAccountsResponse = data;
93
93
  }
94
94
  catch (err) {
95
- uiLogger.debug('Unable to fetch developer test account usage limits: ', err);
95
+ uiLogger.error(lib.prompts.projectDevTargetAccountPrompt.fetchDeveloperTestAccountsError);
96
+ throw new PromptExitError(lib.prompts.projectDevTargetAccountPrompt.fetchDeveloperTestAccountsError, EXIT_CODES.ERROR);
96
97
  }
97
98
  let disabledMessage = false;
98
99
  if (devTestAccountsResponse &&
@@ -10,7 +10,7 @@ import { EXIT_CODES } from '../enums/exitCodes.js';
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = path.dirname(__filename);
12
12
  // cms-dev-server version to install to isolated cache
13
- const TARGET_CMS_DEV_SERVER_VERSION = '1.2.26';
13
+ const TARGET_CMS_DEV_SERVER_VERSION = '1.2.44';
14
14
  /**
15
15
  * Ensures cms-dev-server is installed in an isolated cache directory.
16
16
  * This prevents React version conflicts with the CLI.
@@ -19,3 +19,4 @@ export declare function trackHelpUsage(command: string): Promise<void>;
19
19
  export declare function trackConvertFieldsUsage(command: string): Promise<void>;
20
20
  export declare function trackAuthAction(command: string, authType: string, step: string, accountId?: number): Promise<void>;
21
21
  export declare function trackCommandMetadataUsage(command: string, meta?: UsageTrackingMeta, accountId?: number): Promise<void>;
22
+ export declare function trackMcpPromotionShown(command?: string): Promise<void>;
@@ -171,6 +171,15 @@ export async function trackCommandMetadataUsage(command, meta = {}, accountId) {
171
171
  meta,
172
172
  });
173
173
  }
174
+ export async function trackMcpPromotionShown(command) {
175
+ return trackCliInteraction({
176
+ action: 'cli-mcp-promotion',
177
+ command: command ?? 'mcp-promotion',
178
+ meta: {
179
+ step: 'shown',
180
+ },
181
+ });
182
+ }
174
183
  async function trackCliInteraction({ action, accountId, command, authType, meta = {}, }) {
175
184
  try {
176
185
  const config = getConfig();
@@ -61,7 +61,7 @@ const inputSchema = {
61
61
  commerceLevel: z
62
62
  .enum(ACCOUNT_LEVEL_CHOICES_WITHOUT_STARTER)
63
63
  .optional()
64
- .describe(`Commerce Hub tier level. Options: ${ACCOUNT_LEVEL_CHOICES_WITHOUT_STARTER.join(', ')}. Defaults to ENTERPRISE if not specified.`),
64
+ .describe(`Revenue Hub tier level. Options: ${ACCOUNT_LEVEL_CHOICES_WITHOUT_STARTER.join(', ')}. Defaults to ENTERPRISE if not specified.`),
65
65
  };
66
66
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
67
  const createTestAccountInputSchema = z.object({ ...inputSchema });
@@ -29,7 +29,7 @@ export class UploadProjectTools extends Tool {
29
29
  }
30
30
  async handler({ absoluteProjectPath, absoluteCurrentWorkingDirectory, profile, uploadMessage, }) {
31
31
  setupHubSpotConfig(absoluteCurrentWorkingDirectory);
32
- let command = addFlag('hs project upload', 'force-create', true);
32
+ let command = addFlag('hs project upload', 'force', true);
33
33
  const content = [];
34
34
  if (uploadMessage) {
35
35
  command = addFlag(command, 'message', uploadMessage);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/cli",
3
- "version": "8.9.1",
3
+ "version": "8.10.0-beta.0",
4
4
  "description": "The official CLI for developing on HubSpot",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/HubSpot/hubspot-cli",
@@ -10,10 +10,10 @@
10
10
  "!**/__tests__/**"
11
11
  ],
12
12
  "dependencies": {
13
- "@hubspot/local-dev-lib": "5.8.1",
14
- "@hubspot/project-parsing-lib": "0.17.0",
13
+ "@hubspot/local-dev-lib": "5.9.0",
14
+ "@hubspot/project-parsing-lib": "0.19.1",
15
15
  "@hubspot/serverless-dev-runtime": "7.0.7",
16
- "@hubspot/ui-extensions-dev-server": "2.0.9",
16
+ "@hubspot/ui-extensions-dev-server": "2.0.10",
17
17
  "@inquirer/prompts": "7.1.0",
18
18
  "@modelcontextprotocol/sdk": "1.29.0",
19
19
  "archiver": "7.0.1",
@@ -33,6 +33,7 @@
33
33
  "open": "7.4.2",
34
34
  "p-queue": "8.1.0",
35
35
  "react": "19.2.3",
36
+ "semver": "7.6.3",
36
37
  "strip-ansi": "7.1.0",
37
38
  "table": "6.9.0",
38
39
  "tmp": "0.2.4",
@@ -67,7 +68,6 @@
67
68
  "madge": "^8.0.0",
68
69
  "mock-stdin": "^1.0.0",
69
70
  "prettier": "^3.4.2",
70
- "semver": "^7.6.3",
71
71
  "ts-node": "^10.9.2",
72
72
  "tsx": "^4.20.3",
73
73
  "typescript": "^5.6.2",
@@ -0,0 +1,37 @@
1
+ import { AccountType, Environment } from '@hubspot/local-dev-lib/types/Accounts';
2
+ import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
3
+ import { ProjectConfig } from './Projects.js';
4
+ export declare const ACCOUNT_TARGET_SELECTION_SOURCES: {
5
+ readonly EXPLICIT_ACCOUNT: "explicit-account";
6
+ readonly ENV_CONFIG: "env-config";
7
+ readonly PROFILE: "profile";
8
+ readonly LINKED_DIRECTORY: "linked-directory";
9
+ readonly GLOBAL_DEFAULT: "global-default";
10
+ };
11
+ export type AccountTargetSelectionSource = ValueOf<typeof ACCOUNT_TARGET_SELECTION_SOURCES>;
12
+ export declare const ACCOUNT_TARGET_CATEGORIES: {
13
+ readonly RECOMMENDED_TESTING: "recommended-testing";
14
+ readonly PRODUCTION_WITH_CARE: "production-with-care";
15
+ readonly UNKNOWN: "unknown";
16
+ };
17
+ export type AccountTargetCategory = ValueOf<typeof ACCOUNT_TARGET_CATEGORIES>;
18
+ export type AccountTargetCandidate = {
19
+ accountId: number;
20
+ accountName?: string;
21
+ accountType?: AccountType;
22
+ environment?: Environment;
23
+ source: AccountTargetSelectionSource;
24
+ category: AccountTargetCategory;
25
+ profileName?: string;
26
+ };
27
+ export type DiscoverAccountTargetsOptions = {
28
+ explicitAccount?: string | number;
29
+ useEnv?: boolean;
30
+ profileName?: string;
31
+ projectDir?: string | null;
32
+ projectConfig?: ProjectConfig | null;
33
+ };
34
+ export type DiscoverAccountTargetsResult = {
35
+ candidates: AccountTargetCandidate[];
36
+ recommended?: AccountTargetCandidate;
37
+ };
@@ -0,0 +1,12 @@
1
+ export const ACCOUNT_TARGET_SELECTION_SOURCES = {
2
+ EXPLICIT_ACCOUNT: 'explicit-account',
3
+ ENV_CONFIG: 'env-config',
4
+ PROFILE: 'profile',
5
+ LINKED_DIRECTORY: 'linked-directory',
6
+ GLOBAL_DEFAULT: 'global-default',
7
+ };
8
+ export const ACCOUNT_TARGET_CATEGORIES = {
9
+ RECOMMENDED_TESTING: 'recommended-testing',
10
+ PRODUCTION_WITH_CARE: 'production-with-care',
11
+ UNKNOWN: 'unknown',
12
+ };
@@ -5,8 +5,9 @@ import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
5
5
  import { Project } from '@hubspot/local-dev-lib/types/Project';
6
6
  import { ProjectConfig } from './Projects.js';
7
7
  import LocalDevState from '../lib/projects/localDev/LocalDevState.js';
8
- import { APP_INSTALLATION_STATES, LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants.js';
8
+ import { LOCAL_DEV_UI_MESSAGE_RECEIVE_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES } from '../lib/constants.js';
9
9
  import { ExitFunction } from './Yargs.js';
10
+ import type { AppInstallationState } from './ProjectComponents.js';
10
11
  export type LocalDevActions = {
11
12
  exit: ExitFunction;
12
13
  };
@@ -36,7 +37,7 @@ export type AppLocalDevData = {
36
37
  id: number;
37
38
  clientId: string;
38
39
  name: string;
39
- installationState: ValueOf<typeof APP_INSTALLATION_STATES>;
40
+ installationState: AppInstallationState;
40
41
  scopeGroupIds: number[];
41
42
  };
42
43
  export type LocalDevServerMessage = ValueOf<typeof LOCAL_DEV_SERVER_MESSAGE_TYPES>;
@@ -1,8 +1,9 @@
1
1
  import type { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/translate';
2
- import { IR_COMPONENT_TYPES, APP_DISTRIBUTION_TYPES, APP_AUTH_TYPES } from '../lib/constants.js';
2
+ import { IR_COMPONENT_TYPES, APP_DISTRIBUTION_TYPES, APP_AUTH_TYPES, APP_INSTALLATION_STATES } from '../lib/constants.js';
3
3
  import { ValueOf } from '@hubspot/local-dev-lib/types/Utils';
4
4
  type AppDistributionType = ValueOf<typeof APP_DISTRIBUTION_TYPES>;
5
5
  type AppAuthType = ValueOf<typeof APP_AUTH_TYPES>;
6
+ export type AppInstallationState = ValueOf<typeof APP_INSTALLATION_STATES>;
6
7
  type AppConfig = {
7
8
  description: string;
8
9
  name: string;