@hubspot/cli 7.7.21-experimental.0 → 7.7.22-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.
- package/bin/cli.js +6 -2
- package/commands/__tests__/getStarted.test.js +0 -10
- package/commands/create/api-sample.d.ts +1 -1
- package/commands/create/app.d.ts +1 -1
- package/commands/create/function.d.ts +1 -1
- package/commands/create/index.d.ts +1 -1
- package/commands/create/module.d.ts +1 -1
- package/commands/create/react-app.d.ts +1 -1
- package/commands/create/template.d.ts +1 -1
- package/commands/create/vue-app.d.ts +1 -1
- package/commands/create/webpack-serverless.d.ts +1 -1
- package/commands/create/website-theme.d.ts +1 -1
- package/commands/create.d.ts +1 -1
- package/commands/getStarted.js +12 -27
- package/commands/mcp/setup.js +1 -0
- package/commands/mcp/start.d.ts +4 -1
- package/commands/mcp/start.js +8 -3
- package/commands/project/__tests__/deploy.test.js +28 -26
- package/commands/project/__tests__/devUnifiedFlow.test.js +19 -16
- package/commands/project/create.js +2 -2
- package/commands/project/deploy.d.ts +3 -2
- package/commands/project/deploy.js +63 -54
- package/commands/project/dev/unifiedFlow.js +7 -6
- package/commands/testAccount/__tests__/createConfig.test.js +0 -3
- package/commands/testAccount/create.js +12 -25
- package/commands/testAccount/createConfig.d.ts +0 -2
- package/commands/testAccount/createConfig.js +8 -9
- package/lang/en.d.ts +40 -23
- package/lang/en.js +41 -24
- package/lang/en.lyaml +0 -26
- package/lib/__tests__/buildAccount.test.js +31 -3
- package/lib/__tests__/usageTracking.test.js +8 -14
- package/lib/buildAccount.d.ts +8 -2
- package/lib/buildAccount.js +54 -5
- package/lib/mcp/setup.js +26 -5
- package/lib/projects/add/legacyAddComponent.js +2 -2
- package/lib/projects/add/v3AddComponent.js +2 -2
- package/lib/projects/localDev/DevServerManager.js +0 -2
- package/lib/projects/localDev/DevServerManagerV2.js +0 -2
- package/lib/projects/localDev/helpers.d.ts +1 -1
- package/lib/projects/localDev/helpers.js +2 -2
- package/lib/projects/upload.js +1 -1
- package/lib/prompts/createApiSamplePrompt.d.ts +1 -1
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +11 -10
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +73 -31
- package/lib/prompts/promptUtils.js +66 -56
- package/lib/prompts/sandboxesPrompt.d.ts +1 -1
- package/lib/sandboxSync.d.ts +1 -1
- package/lib/sandboxes.d.ts +1 -1
- package/lib/schema.js +5 -1
- package/lib/ui/index.js +1 -1
- package/lib/usageTracking.d.ts +11 -0
- package/lib/usageTracking.js +66 -75
- package/mcp-server/tools/project/AddFeatureToProject.js +4 -1
- package/mcp-server/tools/project/CreateProjectTool.d.ts +2 -2
- package/mcp-server/tools/project/CreateProjectTool.js +4 -1
- package/mcp-server/tools/project/DeployProject.js +4 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +4 -1
- package/mcp-server/tools/project/UploadProjectTools.js +4 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +4 -1
- package/mcp-server/tools/project/__tests__/AddFeatureToProject.test.js +1 -0
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -0
- package/mcp-server/tools/project/__tests__/DeployProject.test.js +1 -0
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -0
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -0
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -0
- package/mcp-server/utils/__tests__/project.test.js +9 -6
- package/mcp-server/utils/project.js +3 -0
- package/mcp-server/utils/toolUsageTracking.d.ts +1 -0
- package/mcp-server/utils/toolUsageTracking.js +22 -0
- package/package.json +4 -4
- /package/types/{cms.d.ts → Cms.d.ts} +0 -0
- /package/types/{cms.js → Cms.js} +0 -0
- /package/types/{sandboxes.d.ts → Sandboxes.d.ts} +0 -0
- /package/types/{sandboxes.js → Sandboxes.js} +0 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { DeveloperTestAccountConfig } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
|
|
1
|
+
import { AccountLevel, DeveloperTestAccountConfig } from '@hubspot/local-dev-lib/types/developerTestAccounts.js';
|
|
2
2
|
declare const hubs: {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
MARKETING: string;
|
|
4
|
+
OPS: string;
|
|
5
|
+
SERVICE: string;
|
|
6
|
+
SALES: string;
|
|
7
|
+
CONTENT: string;
|
|
8
8
|
};
|
|
9
9
|
type HubName = keyof typeof hubs;
|
|
10
|
-
type
|
|
11
|
-
|
|
10
|
+
export type HubConfig = {
|
|
11
|
+
hub: HubName;
|
|
12
|
+
tier: AccountLevel;
|
|
13
|
+
};
|
|
12
14
|
export declare function createDeveloperTestAccountConfigPrompt(args?: {
|
|
13
15
|
name?: string;
|
|
14
16
|
description?: string;
|
|
15
|
-
|
|
16
|
-
}): Promise<DeveloperTestAccountConfig>;
|
|
17
|
+
}, supportFlags?: boolean): Promise<DeveloperTestAccountConfig>;
|
|
17
18
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { Separator } from '@inquirer/prompts';
|
|
1
2
|
import { lib } from '../../lang/en.js';
|
|
2
3
|
import { promptUser } from './promptUtils.js';
|
|
3
|
-
import { Separator } from '@inquirer/prompts';
|
|
4
4
|
const hubs = {
|
|
5
5
|
MARKETING: 'marketingLevel',
|
|
6
6
|
OPS: 'opsLevel',
|
|
@@ -8,63 +8,108 @@ const hubs = {
|
|
|
8
8
|
SALES: 'salesLevel',
|
|
9
9
|
CONTENT: 'contentLevel',
|
|
10
10
|
};
|
|
11
|
+
const AccountTiers = {
|
|
12
|
+
FREE: 'FREE',
|
|
13
|
+
STARTER: 'STARTER',
|
|
14
|
+
PROFESSIONAL: 'PROFESSIONAL',
|
|
15
|
+
ENTERPRISE: 'ENTERPRISE',
|
|
16
|
+
};
|
|
17
|
+
const makeHubTiers = (hubKey) => {
|
|
18
|
+
const hubTypeKey = hubKey.toLowerCase();
|
|
19
|
+
const hubName = lib.prompts.createDeveloperTestAccountConfigPrompt.hubTypes[hubTypeKey];
|
|
20
|
+
return [
|
|
21
|
+
{
|
|
22
|
+
name: `${hubName} [${AccountTiers.FREE}]`,
|
|
23
|
+
value: { hub: hubKey, tier: AccountTiers.FREE },
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: `${hubName} [${AccountTiers.STARTER}]`,
|
|
27
|
+
value: { hub: hubKey, tier: AccountTiers.STARTER },
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: `${hubName} [${AccountTiers.PROFESSIONAL}]`,
|
|
31
|
+
value: { hub: hubKey, tier: AccountTiers.PROFESSIONAL },
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: `${hubName} [${AccountTiers.ENTERPRISE}]`,
|
|
35
|
+
value: { hub: hubKey, tier: AccountTiers.ENTERPRISE },
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
};
|
|
11
39
|
const TEST_ACCOUNT_TIERS = [
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
name: 'Marketing PROFESSIONAL',
|
|
15
|
-
value: 'MARKETING:PROFESSIONAL',
|
|
16
|
-
},
|
|
17
|
-
{ name: 'Marketing ENTERPRISE', value: 'MARKETING:ENTERPRISE' },
|
|
40
|
+
...makeHubTiers('MARKETING'),
|
|
18
41
|
new Separator(),
|
|
19
|
-
|
|
20
|
-
{ name: 'Ops PROFESSIONAL', value: 'OPS:PROFESSIONAL' },
|
|
21
|
-
{ name: 'Ops ENTERPRISE', value: 'OPS:ENTERPRISE' },
|
|
42
|
+
...makeHubTiers('OPS'),
|
|
22
43
|
new Separator(),
|
|
23
|
-
|
|
24
|
-
{ name: 'Service PROFESSIONAL', value: 'SERVICE:PROFESSIONAL' },
|
|
25
|
-
{ name: 'Service ENTERPRISE', value: 'SERVICE:ENTERPRISE' },
|
|
44
|
+
...makeHubTiers('SERVICE'),
|
|
26
45
|
new Separator(),
|
|
27
|
-
|
|
28
|
-
{ name: 'Sales PROFESSIONAL', value: 'SALES:PROFESSIONAL' },
|
|
29
|
-
{ name: 'Sales ENTERPRISE', value: 'SALES:ENTERPRISE' },
|
|
46
|
+
...makeHubTiers('SALES'),
|
|
30
47
|
new Separator(),
|
|
31
|
-
|
|
32
|
-
{ name: 'Content PROFESSIONAL', value: 'CONTENT:PROFESSIONAL' },
|
|
33
|
-
{ name: 'Content ENTERPRISE', value: 'CONTENT:ENTERPRISE' },
|
|
48
|
+
...makeHubTiers('CONTENT'),
|
|
34
49
|
new Separator(),
|
|
35
50
|
];
|
|
36
|
-
export async function createDeveloperTestAccountConfigPrompt(args = {}) {
|
|
37
|
-
const { name, description
|
|
51
|
+
export async function createDeveloperTestAccountConfigPrompt(args = {}, supportFlags = true) {
|
|
52
|
+
const { name, description } = args;
|
|
38
53
|
let accountName = name;
|
|
39
54
|
let accountDescription = description;
|
|
40
|
-
let accountLevelsArray =
|
|
55
|
+
let accountLevelsArray = [];
|
|
41
56
|
if (!accountName) {
|
|
42
57
|
const namePromptResult = await promptUser({
|
|
43
58
|
name: 'accountName',
|
|
44
|
-
message: lib.prompts.createDeveloperTestAccountConfigPrompt.namePrompt,
|
|
59
|
+
message: lib.prompts.createDeveloperTestAccountConfigPrompt.namePrompt(supportFlags),
|
|
45
60
|
type: 'input',
|
|
61
|
+
validate: value => {
|
|
62
|
+
if (!value) {
|
|
63
|
+
return lib.prompts.createDeveloperTestAccountConfigPrompt.errors
|
|
64
|
+
.nameRequired;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
},
|
|
46
68
|
});
|
|
47
69
|
accountName = namePromptResult.accountName;
|
|
48
70
|
}
|
|
49
71
|
if (!accountDescription) {
|
|
50
72
|
const descriptionPromptResult = await promptUser({
|
|
51
73
|
name: 'description',
|
|
52
|
-
message: lib.prompts.createDeveloperTestAccountConfigPrompt.descriptionPrompt,
|
|
74
|
+
message: lib.prompts.createDeveloperTestAccountConfigPrompt.descriptionPrompt(supportFlags),
|
|
53
75
|
type: 'input',
|
|
54
76
|
});
|
|
55
77
|
accountDescription = descriptionPromptResult.description;
|
|
56
78
|
}
|
|
57
|
-
|
|
79
|
+
const useDefaultAccountLevelsPromptResult = await promptUser({
|
|
80
|
+
name: 'useDefaultAccountLevels',
|
|
81
|
+
message: lib.prompts.createDeveloperTestAccountConfigPrompt
|
|
82
|
+
.useDefaultAccountLevelsPrompt.message,
|
|
83
|
+
type: 'list',
|
|
84
|
+
choices: [
|
|
85
|
+
{
|
|
86
|
+
name: lib.prompts.createDeveloperTestAccountConfigPrompt
|
|
87
|
+
.useDefaultAccountLevelsPrompt.default,
|
|
88
|
+
value: 'default',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: lib.prompts.createDeveloperTestAccountConfigPrompt
|
|
92
|
+
.useDefaultAccountLevelsPrompt.manual,
|
|
93
|
+
value: 'manual',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
if (useDefaultAccountLevelsPromptResult.useDefaultAccountLevels === 'manual') {
|
|
58
98
|
const accountLevelsPromptResult = await promptUser({
|
|
59
99
|
name: 'testAccountLevels',
|
|
60
100
|
message: lib.prompts.createDeveloperTestAccountConfigPrompt.tiersPrompt,
|
|
61
101
|
type: 'checkbox',
|
|
102
|
+
pageSize: 13,
|
|
62
103
|
choices: TEST_ACCOUNT_TIERS,
|
|
63
104
|
validate: choices => {
|
|
64
|
-
if (choices?.length
|
|
105
|
+
if (choices?.length < Object.keys(hubs).length) {
|
|
106
|
+
return lib.prompts.createDeveloperTestAccountConfigPrompt.errors
|
|
107
|
+
.allHubsRequired;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
65
110
|
const hubMap = {};
|
|
66
111
|
for (const choice of choices) {
|
|
67
|
-
const hub = choice.
|
|
112
|
+
const { hub } = choice.value;
|
|
68
113
|
if (hubMap[hub]) {
|
|
69
114
|
return lib.prompts.createDeveloperTestAccountConfigPrompt.errors
|
|
70
115
|
.tiersError;
|
|
@@ -77,11 +122,8 @@ export async function createDeveloperTestAccountConfigPrompt(args = {}) {
|
|
|
77
122
|
});
|
|
78
123
|
accountLevelsArray = accountLevelsPromptResult.testAccountLevels;
|
|
79
124
|
}
|
|
80
|
-
if (!accountLevelsArray) {
|
|
81
|
-
accountLevelsArray = [];
|
|
82
|
-
}
|
|
83
125
|
const accountLevels = accountLevelsArray.reduce((acc, level) => {
|
|
84
|
-
const
|
|
126
|
+
const { hub: hubName, tier: hubTier } = level;
|
|
85
127
|
const hubLevel = hubs[hubName];
|
|
86
128
|
acc[hubLevel] = hubTier;
|
|
87
129
|
return acc;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { confirm, Separator as _Separator, select, input, checkbox, password, number, } from '@inquirer/prompts';
|
|
2
|
+
import { EXIT_CODES } from '../enums/exitCodes.js';
|
|
2
3
|
export const Separator = new _Separator();
|
|
4
|
+
function isUserCancellationError(error) {
|
|
5
|
+
return error instanceof Error && error.name === 'ExitPromptError';
|
|
6
|
+
}
|
|
3
7
|
function mapPromptChoicesToChoices(choices) {
|
|
4
8
|
return (choices?.map(choice => {
|
|
5
9
|
if (typeof choice === 'string') {
|
|
@@ -16,68 +20,74 @@ function mapPromptChoicesToChoices(choices) {
|
|
|
16
20
|
};
|
|
17
21
|
}) || []);
|
|
18
22
|
}
|
|
19
|
-
function handleArrayConfig(config) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (typeof prompt.message === 'function') {
|
|
32
|
-
prompt.message = prompt.message(result);
|
|
23
|
+
async function handleArrayConfig(config) {
|
|
24
|
+
const result = {};
|
|
25
|
+
for (const prompt of config) {
|
|
26
|
+
if (prompt.when !== undefined) {
|
|
27
|
+
const shouldPrompt = typeof prompt.when === 'function'
|
|
28
|
+
? prompt.when()
|
|
29
|
+
: (prompt.when ?? true);
|
|
30
|
+
if (!shouldPrompt) {
|
|
31
|
+
continue;
|
|
33
32
|
}
|
|
34
|
-
// Pass the accumulated results to each prompt
|
|
35
|
-
const promptWithAnswers = {
|
|
36
|
-
...prompt,
|
|
37
|
-
default: typeof prompt.default === 'function'
|
|
38
|
-
? (answers) => {
|
|
39
|
-
const mergedAnswers = { ...answers, ...result };
|
|
40
|
-
return prompt.default(mergedAnswers);
|
|
41
|
-
}
|
|
42
|
-
: prompt.default,
|
|
43
|
-
};
|
|
44
|
-
const response = await promptUser(promptWithAnswers);
|
|
45
|
-
Object.assign(result, response);
|
|
46
33
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
34
|
+
if (typeof prompt.message === 'function') {
|
|
35
|
+
prompt.message = prompt.message(result);
|
|
36
|
+
}
|
|
37
|
+
// Pass the accumulated results to each prompt
|
|
38
|
+
const promptWithAnswers = {
|
|
39
|
+
...prompt,
|
|
40
|
+
default: typeof prompt.default === 'function'
|
|
41
|
+
? (answers) => {
|
|
42
|
+
const mergedAnswers = { ...answers, ...result };
|
|
43
|
+
return prompt.default(mergedAnswers);
|
|
44
|
+
}
|
|
45
|
+
: prompt.default,
|
|
46
|
+
};
|
|
47
|
+
const response = await promptUser(promptWithAnswers);
|
|
48
|
+
Object.assign(result, response);
|
|
53
49
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
export async function promptUser(config) {
|
|
53
|
+
try {
|
|
54
|
+
if (Array.isArray(config)) {
|
|
55
|
+
return await handleArrayConfig(config);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
if (config.when !== undefined) {
|
|
59
|
+
const shouldPrompt = typeof config.when === 'function'
|
|
60
|
+
? config.when()
|
|
61
|
+
: (config.when ?? true);
|
|
62
|
+
if (!shouldPrompt) {
|
|
63
|
+
return Promise.resolve({});
|
|
64
|
+
}
|
|
61
65
|
}
|
|
62
66
|
}
|
|
67
|
+
switch (config.type) {
|
|
68
|
+
case 'list':
|
|
69
|
+
return await handleSelectPrompt(config);
|
|
70
|
+
case 'input':
|
|
71
|
+
return await handleInputPrompt(config);
|
|
72
|
+
case 'confirm':
|
|
73
|
+
return await handleConfirmPrompt(config);
|
|
74
|
+
case 'checkbox':
|
|
75
|
+
return await handleCheckboxPrompt(config);
|
|
76
|
+
case 'password':
|
|
77
|
+
return await handlePasswordPrompt(config);
|
|
78
|
+
case 'number':
|
|
79
|
+
return await handleNumberPrompt(config);
|
|
80
|
+
case 'rawlist':
|
|
81
|
+
return await handleRawListPrompt(config);
|
|
82
|
+
default:
|
|
83
|
+
return await handleInputPrompt(config);
|
|
84
|
+
}
|
|
63
85
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
case 'confirm':
|
|
70
|
-
return handleConfirmPrompt(config);
|
|
71
|
-
case 'checkbox':
|
|
72
|
-
return handleCheckboxPrompt(config);
|
|
73
|
-
case 'password':
|
|
74
|
-
return handlePasswordPrompt(config);
|
|
75
|
-
case 'number':
|
|
76
|
-
return handleNumberPrompt(config);
|
|
77
|
-
case 'rawlist':
|
|
78
|
-
return handleRawListPrompt(config);
|
|
79
|
-
default:
|
|
80
|
-
return handleInputPrompt(config);
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (isUserCancellationError(error)) {
|
|
88
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
89
|
+
}
|
|
90
|
+
throw error;
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
function handleRawListPrompt(config) {
|
package/lib/sandboxSync.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
2
|
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
3
|
-
import { SandboxSyncTask } from '../types/
|
|
3
|
+
import { SandboxSyncTask } from '../types/Sandboxes.js';
|
|
4
4
|
export declare function syncSandbox(accountConfig: CLIAccount, parentAccountConfig: CLIAccount, env: Environment, syncTasks: Array<SandboxSyncTask>, slimInfoMessage?: boolean): Promise<void>;
|
package/lib/sandboxes.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AccountType, CLIAccount } from '@hubspot/local-dev-lib/types/Accounts';
|
|
2
2
|
import { Environment } from '@hubspot/local-dev-lib/types/Config';
|
|
3
|
-
import { SandboxSyncTask, SandboxAccountType } from '../types/
|
|
3
|
+
import { SandboxSyncTask, SandboxAccountType } from '../types/Sandboxes.js';
|
|
4
4
|
export declare const SYNC_TYPES: {
|
|
5
5
|
readonly OBJECT_RECORDS: "object-records";
|
|
6
6
|
};
|
package/lib/schema.js
CHANGED
|
@@ -6,6 +6,10 @@ export function logSchemas(schemas) {
|
|
|
6
6
|
const data = schemas
|
|
7
7
|
.map(r => [r.labels.singular, r.name, r.objectTypeId || ''])
|
|
8
8
|
.sort((a, b) => (a[1] > b[1] ? 1 : -1));
|
|
9
|
+
if (data.length === 0) {
|
|
10
|
+
logger.log('No Schemas were found');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
9
13
|
data.unshift([
|
|
10
14
|
chalk.bold('Label'),
|
|
11
15
|
chalk.bold('Name'),
|
|
@@ -15,7 +19,7 @@ export function logSchemas(schemas) {
|
|
|
15
19
|
singleLine: true,
|
|
16
20
|
border: getBorderCharacters('honeywell'),
|
|
17
21
|
};
|
|
18
|
-
logger.log(
|
|
22
|
+
logger.log(table(data, tableConfig));
|
|
19
23
|
}
|
|
20
24
|
export async function listSchemas(accountId) {
|
|
21
25
|
const { data } = await fetchObjectSchemas(accountId);
|
package/lib/ui/index.js
CHANGED
|
@@ -41,7 +41,7 @@ export function uiAccountDescription(accountId, bold = true) {
|
|
|
41
41
|
const account = getAccountConfig(accountId || undefined);
|
|
42
42
|
let message;
|
|
43
43
|
if (account && account.accountType) {
|
|
44
|
-
message = `${account.name} [${HUBSPOT_ACCOUNT_TYPE_STRINGS[account.accountType]}] (${accountId})`;
|
|
44
|
+
message = `${account.name ? `${account.name} ` : ''}[${HUBSPOT_ACCOUNT_TYPE_STRINGS[account.accountType]}] (${accountId})`;
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
47
|
message = accountId ? accountId.toString() : '';
|
package/lib/usageTracking.d.ts
CHANGED
|
@@ -13,6 +13,17 @@ type Meta = {
|
|
|
13
13
|
file?: boolean;
|
|
14
14
|
successful?: boolean;
|
|
15
15
|
};
|
|
16
|
+
export declare const EventClass: {
|
|
17
|
+
USAGE: string;
|
|
18
|
+
INTERACTION: string;
|
|
19
|
+
VIEW: string;
|
|
20
|
+
ACTIVATION: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function getNodeVersionData(): {
|
|
23
|
+
nodeVersion: string;
|
|
24
|
+
nodeMajorVersion: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function getPlatform(): string;
|
|
16
27
|
export declare function trackCommandUsage(command: string, meta?: Meta, accountId?: number): Promise<void>;
|
|
17
28
|
export declare function trackHelpUsage(command: string): Promise<void>;
|
|
18
29
|
export declare function trackConvertFieldsUsage(command: string): Promise<void>;
|
package/lib/usageTracking.js
CHANGED
|
@@ -5,19 +5,19 @@ import { logger } from '@hubspot/local-dev-lib/logger';
|
|
|
5
5
|
import packageJson from '../package.json' with { type: 'json' };
|
|
6
6
|
const version = packageJson.version;
|
|
7
7
|
import { debugError } from './errorHandlers/index.js';
|
|
8
|
-
const EventClass = {
|
|
8
|
+
export const EventClass = {
|
|
9
9
|
USAGE: 'USAGE',
|
|
10
10
|
INTERACTION: 'INTERACTION',
|
|
11
11
|
VIEW: 'VIEW',
|
|
12
12
|
ACTIVATION: 'ACTIVATION',
|
|
13
13
|
};
|
|
14
|
-
function getNodeVersionData() {
|
|
14
|
+
export function getNodeVersionData() {
|
|
15
15
|
return {
|
|
16
16
|
nodeVersion: process.version,
|
|
17
17
|
nodeMajorVersion: (process.version || '').split('.')[0],
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
function getPlatform() {
|
|
20
|
+
export function getPlatform() {
|
|
21
21
|
switch (process.platform) {
|
|
22
22
|
case 'darwin':
|
|
23
23
|
return 'macos';
|
|
@@ -40,86 +40,45 @@ export async function trackCommandUsage(command, meta = {}, accountId) {
|
|
|
40
40
|
? accountConfig.authType
|
|
41
41
|
: API_KEY_AUTH_METHOD.value;
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
command,
|
|
50
|
-
authType,
|
|
51
|
-
...meta,
|
|
52
|
-
};
|
|
53
|
-
try {
|
|
54
|
-
await trackUsage('cli-interaction', EventClass.INTERACTION, usageTrackingEvent, accountId);
|
|
55
|
-
logger.debug('Sent usage tracking command event: %o', usageTrackingEvent);
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
debugError(e);
|
|
59
|
-
}
|
|
43
|
+
return trackCliInteraction({
|
|
44
|
+
action: 'cli-command',
|
|
45
|
+
command,
|
|
46
|
+
authType,
|
|
47
|
+
...meta,
|
|
48
|
+
accountId,
|
|
60
49
|
});
|
|
61
50
|
}
|
|
62
51
|
export async function trackHelpUsage(command) {
|
|
63
52
|
if (!isTrackingAllowed()) {
|
|
64
53
|
return;
|
|
65
54
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
logger.debug('Tracking help usage of "%s" sub-command', command);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
logger.debug('Tracking help usage of main command');
|
|
72
|
-
}
|
|
73
|
-
await trackUsage('cli-interaction', EventClass.INTERACTION, {
|
|
74
|
-
action: 'cli-help',
|
|
75
|
-
os: getPlatform(),
|
|
76
|
-
...getNodeVersionData(),
|
|
77
|
-
version,
|
|
78
|
-
command,
|
|
79
|
-
});
|
|
55
|
+
if (command) {
|
|
56
|
+
logger.debug('Tracking help usage of "%s" sub-command', command);
|
|
80
57
|
}
|
|
81
|
-
|
|
82
|
-
|
|
58
|
+
else {
|
|
59
|
+
logger.debug('Tracking help usage of main command');
|
|
83
60
|
}
|
|
61
|
+
return trackCliInteraction({
|
|
62
|
+
action: 'cli-help',
|
|
63
|
+
command,
|
|
64
|
+
});
|
|
84
65
|
}
|
|
85
66
|
export async function trackConvertFieldsUsage(command) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
logger.debug('Attempting to track usage of "%s" command', command);
|
|
91
|
-
await trackUsage('cli-interaction', EventClass.INTERACTION, {
|
|
92
|
-
action: 'cli-process-fields',
|
|
93
|
-
os: getPlatform(),
|
|
94
|
-
...getNodeVersionData(),
|
|
95
|
-
version,
|
|
96
|
-
command,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
debugError(e);
|
|
101
|
-
}
|
|
67
|
+
return trackCliInteraction({
|
|
68
|
+
action: 'cli-process-fields',
|
|
69
|
+
command,
|
|
70
|
+
});
|
|
102
71
|
}
|
|
103
72
|
export async function trackAuthAction(command, authType, step, accountId) {
|
|
104
|
-
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const usageTrackingEvent = {
|
|
73
|
+
return trackCliInteraction({
|
|
108
74
|
action: 'cli-auth',
|
|
109
|
-
os: getPlatform(),
|
|
110
|
-
...getNodeVersionData(),
|
|
111
|
-
version,
|
|
112
75
|
command,
|
|
113
76
|
authType,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
debugError(e);
|
|
122
|
-
}
|
|
77
|
+
accountId,
|
|
78
|
+
meta: {
|
|
79
|
+
step,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
123
82
|
}
|
|
124
83
|
export async function trackCommandMetadataUsage(command, meta = {}, accountId) {
|
|
125
84
|
if (!isTrackingAllowed()) {
|
|
@@ -134,9 +93,21 @@ export async function trackCommandMetadataUsage(command, meta = {}, accountId) {
|
|
|
134
93
|
? accountConfig.authType
|
|
135
94
|
: API_KEY_AUTH_METHOD.value;
|
|
136
95
|
}
|
|
137
|
-
|
|
96
|
+
return trackCliInteraction({
|
|
97
|
+
action: 'cli-command-metadata',
|
|
98
|
+
command,
|
|
99
|
+
authType,
|
|
100
|
+
accountId,
|
|
101
|
+
meta,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async function trackCliInteraction({ action, accountId, command, authType, meta = {}, }) {
|
|
105
|
+
try {
|
|
106
|
+
if (!isTrackingAllowed()) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
138
109
|
const usageTrackingEvent = {
|
|
139
|
-
action
|
|
110
|
+
action,
|
|
140
111
|
os: getPlatform(),
|
|
141
112
|
...getNodeVersionData(),
|
|
142
113
|
version,
|
|
@@ -144,12 +115,32 @@ export async function trackCommandMetadataUsage(command, meta = {}, accountId) {
|
|
|
144
115
|
authType,
|
|
145
116
|
...meta,
|
|
146
117
|
};
|
|
118
|
+
if (process.env.HUBSPOT_MCP_AI_AGENT) {
|
|
119
|
+
try {
|
|
120
|
+
await trackUsage('cli-interaction', EventClass.INTERACTION, {
|
|
121
|
+
...usageTrackingEvent,
|
|
122
|
+
action: 'cli-mcp-server',
|
|
123
|
+
type: process.env.HUBSPOT_MCP_AI_AGENT,
|
|
124
|
+
}, accountId);
|
|
125
|
+
logger.debug('Sent AI usage tracking command event: %o', {
|
|
126
|
+
...usageTrackingEvent,
|
|
127
|
+
action: 'cli-mcp-server',
|
|
128
|
+
type: process.env.HUBSPOT_MCP_AI_AGENT,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
debugError(error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
147
135
|
try {
|
|
148
|
-
|
|
149
|
-
logger.debug('Sent usage tracking command event: %o', usageTrackingEvent);
|
|
136
|
+
return trackUsage('cli-interaction', EventClass.INTERACTION, usageTrackingEvent, accountId);
|
|
150
137
|
}
|
|
151
|
-
catch (
|
|
152
|
-
debugError(
|
|
138
|
+
catch (error) {
|
|
139
|
+
debugError(error);
|
|
153
140
|
}
|
|
154
|
-
|
|
141
|
+
logger.debug('Sent usage tracking command event: %o', usageTrackingEvent);
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
debugError(e);
|
|
145
|
+
}
|
|
155
146
|
}
|
|
@@ -5,6 +5,7 @@ import { addFlag } from '../../utils/command.js';
|
|
|
5
5
|
import { absoluteProjectPath } from './constants.js';
|
|
6
6
|
import { runCommandInDir } from '../../utils/project.js';
|
|
7
7
|
import { formatTextContents, formatTextContent } from '../../utils/content.js';
|
|
8
|
+
import { trackToolUsage } from '../../utils/toolUsageTracking.js';
|
|
8
9
|
const inputSchema = {
|
|
9
10
|
absoluteProjectPath,
|
|
10
11
|
addApp: z
|
|
@@ -37,12 +38,14 @@ const inputSchema = {
|
|
|
37
38
|
const inputSchemaZodObject = z.object({
|
|
38
39
|
...inputSchema,
|
|
39
40
|
});
|
|
41
|
+
const toolName = 'add-feature-to-hubspot-project';
|
|
40
42
|
export class AddFeatureToProject extends Tool {
|
|
41
43
|
constructor(mcpServer) {
|
|
42
44
|
super(mcpServer);
|
|
43
45
|
}
|
|
44
46
|
async handler({ absoluteProjectPath, distribution, auth, features, addApp, }) {
|
|
45
47
|
try {
|
|
48
|
+
await trackToolUsage(toolName);
|
|
46
49
|
let command = `hs project add`;
|
|
47
50
|
const content = [];
|
|
48
51
|
if (distribution) {
|
|
@@ -72,7 +75,7 @@ export class AddFeatureToProject extends Tool {
|
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
register() {
|
|
75
|
-
return this.mcpServer.registerTool(
|
|
78
|
+
return this.mcpServer.registerTool(toolName, {
|
|
76
79
|
title: 'Add feature to HubSpot Project',
|
|
77
80
|
description: 'Adds a feature to an existing HubSpot project',
|
|
78
81
|
inputSchema,
|
|
@@ -13,16 +13,16 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
13
13
|
projectBase: "app" | "empty";
|
|
14
14
|
absoluteCurrentWorkingDirectory: string;
|
|
15
15
|
destination: string;
|
|
16
|
-
auth?: "oauth" | "static" | undefined;
|
|
17
16
|
name?: string | undefined;
|
|
17
|
+
auth?: "oauth" | "static" | undefined;
|
|
18
18
|
distribution?: "marketplace" | "private" | undefined;
|
|
19
19
|
features?: ("card" | "settings" | "app-function" | "webhooks")[] | undefined;
|
|
20
20
|
}, {
|
|
21
21
|
projectBase: "app" | "empty";
|
|
22
22
|
absoluteCurrentWorkingDirectory: string;
|
|
23
23
|
destination: string;
|
|
24
|
-
auth?: "oauth" | "static" | undefined;
|
|
25
24
|
name?: string | undefined;
|
|
25
|
+
auth?: "oauth" | "static" | undefined;
|
|
26
26
|
distribution?: "marketplace" | "private" | undefined;
|
|
27
27
|
features?: ("card" | "settings" | "app-function" | "webhooks")[] | undefined;
|
|
28
28
|
}>;
|