@hubspot/cli 7.7.16-experimental.9 → 7.7.18-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/commands/app.js +1 -6
- package/commands/getStarted.js +8 -14
- package/commands/mcp/setup.js +1 -0
- package/commands/mcp/start.d.ts +4 -1
- package/commands/mcp/start.js +10 -3
- package/commands/testAccount/create.js +5 -27
- package/lang/en.d.ts +1 -25
- package/lang/en.js +1 -25
- package/lib/dependencyManagement.d.ts +1 -1
- package/lib/dependencyManagement.js +2 -2
- package/lib/mcp/setup.js +8 -3
- package/lib/projects/structure.d.ts +2 -2
- package/lib/projects/upload.d.ts +1 -2
- package/lib/projects/upload.js +0 -1
- package/lib/testUtils.js +1 -2
- package/lib/usageTracking.d.ts +5 -5
- package/lib/usageTracking.js +71 -79
- package/mcp-server/tools/project/UploadProjectTools.js +1 -1
- package/mcp-server/utils/project.js +3 -0
- package/package.json +2 -2
- package/commands/app/install.d.ts +0 -8
- package/commands/app/install.js +0 -127
package/commands/app.js
CHANGED
|
@@ -5,17 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const migrate_1 = __importDefault(require("./app/migrate"));
|
|
7
7
|
const secret_1 = __importDefault(require("./app/secret"));
|
|
8
|
-
const install_1 = __importDefault(require("./app/install"));
|
|
9
8
|
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
10
9
|
const command = ['app', 'apps'];
|
|
11
10
|
// Keep the command hidden for now
|
|
12
11
|
const describe = undefined;
|
|
13
12
|
function appBuilder(yargs) {
|
|
14
|
-
yargs
|
|
15
|
-
.command(migrate_1.default)
|
|
16
|
-
.command(secret_1.default)
|
|
17
|
-
.command(install_1.default)
|
|
18
|
-
.demandCommand(1, '');
|
|
13
|
+
yargs.command(migrate_1.default).command(secret_1.default).demandCommand(1, '');
|
|
19
14
|
return yargs;
|
|
20
15
|
}
|
|
21
16
|
const builder = (0, yargsUtils_1.makeYargsBuilder)(appBuilder, command, describe);
|
package/commands/getStarted.js
CHANGED
|
@@ -128,6 +128,7 @@ async function handler(args) {
|
|
|
128
128
|
logger_1.uiLogger.log(en_1.commands.getStarted.prompts.projectCreated.description);
|
|
129
129
|
logger_1.uiLogger.log(' ');
|
|
130
130
|
// 5. Install dependencies - Ask user if they want to install dependencies
|
|
131
|
+
const installLocations = await (0, dependencyManagement_1.getProjectPackageJsonLocations)(projectDest);
|
|
131
132
|
const { shouldInstallDependencies } = await (0, promptUtils_1.promptUser)([
|
|
132
133
|
{
|
|
133
134
|
type: 'confirm',
|
|
@@ -138,24 +139,17 @@ async function handler(args) {
|
|
|
138
139
|
]);
|
|
139
140
|
if (shouldInstallDependencies) {
|
|
140
141
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
logger_1.uiLogger.success(en_1.commands.getStarted.logs.dependenciesInstalled);
|
|
148
|
-
logger_1.uiLogger.log(' ');
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
// Always restore the original working directory
|
|
152
|
-
process.chdir(originalCwd);
|
|
153
|
-
}
|
|
142
|
+
await (0, dependencyManagement_1.installPackages)({
|
|
143
|
+
installLocations: installLocations,
|
|
144
|
+
});
|
|
145
|
+
logger_1.uiLogger.log(' ');
|
|
146
|
+
logger_1.uiLogger.success(en_1.commands.getStarted.logs.dependenciesInstalled);
|
|
147
|
+
logger_1.uiLogger.log(' ');
|
|
154
148
|
}
|
|
155
149
|
catch (err) {
|
|
156
150
|
logger_1.uiLogger.log(' ');
|
|
157
151
|
logger_1.uiLogger.error(en_1.commands.getStarted.errors.installDepsFailed);
|
|
158
|
-
|
|
152
|
+
(0, errorHandlers_1.logError)(err);
|
|
159
153
|
logger_1.uiLogger.log(' ');
|
|
160
154
|
}
|
|
161
155
|
}
|
package/commands/mcp/setup.js
CHANGED
package/commands/mcp/start.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { CommonArgs, YargsCommandModule } from '../../types/Yargs';
|
|
2
|
-
|
|
2
|
+
interface McpStartArgs extends CommonArgs {
|
|
3
|
+
aiAgent: string;
|
|
4
|
+
}
|
|
5
|
+
declare const mcpStartCommand: YargsCommandModule<unknown, McpStartArgs>;
|
|
3
6
|
export default mcpStartCommand;
|
package/commands/mcp/start.js
CHANGED
|
@@ -24,9 +24,9 @@ async function handler(args) {
|
|
|
24
24
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
25
25
|
}
|
|
26
26
|
(0, usageTracking_1.trackCommandUsage)('mcp-start', {}, args.derivedAccountId);
|
|
27
|
-
await startMcpServer();
|
|
27
|
+
await startMcpServer(args.aiAgent);
|
|
28
28
|
}
|
|
29
|
-
async function startMcpServer() {
|
|
29
|
+
async function startMcpServer(aiAgent) {
|
|
30
30
|
try {
|
|
31
31
|
const serverPath = path_1.default.join(__dirname, '..', '..', 'mcp-server', 'server.js');
|
|
32
32
|
// Check if server file exists
|
|
@@ -36,11 +36,13 @@ async function startMcpServer() {
|
|
|
36
36
|
}
|
|
37
37
|
logger_1.uiLogger.info(en_1.commands.mcp.start.startingServer);
|
|
38
38
|
logger_1.uiLogger.info(en_1.commands.mcp.start.stopInstructions);
|
|
39
|
+
const args = [serverPath];
|
|
39
40
|
// Start the server using ts-node
|
|
40
|
-
const child = (0, child_process_1.spawn)(
|
|
41
|
+
const child = (0, child_process_1.spawn)(`node`, args, {
|
|
41
42
|
stdio: 'inherit',
|
|
42
43
|
env: {
|
|
43
44
|
...process.env,
|
|
45
|
+
HUBSPOT_MCP_AI_AGENT: aiAgent || 'unknown',
|
|
44
46
|
},
|
|
45
47
|
});
|
|
46
48
|
// Handle server process events
|
|
@@ -63,6 +65,11 @@ async function startMcpServer() {
|
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
function startBuilder(yargs) {
|
|
68
|
+
yargs
|
|
69
|
+
.option('ai-agent', {
|
|
70
|
+
type: 'string',
|
|
71
|
+
})
|
|
72
|
+
.demandOption('ai-agent');
|
|
66
73
|
return yargs;
|
|
67
74
|
}
|
|
68
75
|
const builder = (0, yargsUtils_1.makeYargsBuilder)(startBuilder, command, describe, {
|
|
@@ -77,13 +77,11 @@ async function handler(args) {
|
|
|
77
77
|
if (formatOutputAsJson) {
|
|
78
78
|
jsonOutput.accountName = data.accountName;
|
|
79
79
|
jsonOutput.accountId = data.id;
|
|
80
|
+
jsonOutput.personalAccessKey = data.personalAccessKey;
|
|
80
81
|
}
|
|
81
82
|
testAccountId = data.id;
|
|
82
83
|
}
|
|
83
84
|
catch (err) {
|
|
84
|
-
SpinniesManager_1.default.fail('createTestAccount', {
|
|
85
|
-
text: en_1.commands.testAccount.create.polling.createFailure,
|
|
86
|
-
});
|
|
87
85
|
(0, errorHandlers_1.logError)(err);
|
|
88
86
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
89
87
|
}
|
|
@@ -95,36 +93,16 @@ async function handler(args) {
|
|
|
95
93
|
successStates: ['SUCCESS'],
|
|
96
94
|
errorStates: [],
|
|
97
95
|
});
|
|
96
|
+
SpinniesManager_1.default.succeed('createTestAccount', {
|
|
97
|
+
text: en_1.commands.testAccount.create.polling.success(testAccountConfig.accountName, testAccountId),
|
|
98
|
+
});
|
|
98
99
|
}
|
|
99
100
|
catch (err) {
|
|
100
101
|
(0, errorHandlers_1.debugError)(err);
|
|
101
102
|
SpinniesManager_1.default.fail('createTestAccount', {
|
|
102
|
-
text: en_1.commands.testAccount.create.polling.
|
|
103
|
+
text: en_1.commands.testAccount.create.polling.failure,
|
|
103
104
|
});
|
|
104
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
105
105
|
}
|
|
106
|
-
if (formatOutputAsJson) {
|
|
107
|
-
// HACK: The status endpoint sometimes returns an early success status.
|
|
108
|
-
// Sleep for an extra 6 minutes to make sure the sync is actually complete.
|
|
109
|
-
await new Promise(resolve => setTimeout(resolve, 360000));
|
|
110
|
-
try {
|
|
111
|
-
// Attempt to generate a new personal access key for the test account now that gate sync is complete.
|
|
112
|
-
const { data } = await (0, developerTestAccounts_1.generateDeveloperTestAccountPersonalAccessKey)(derivedAccountId, testAccountId);
|
|
113
|
-
if (data.personalAccessKey && data.personalAccessKey) {
|
|
114
|
-
jsonOutput.personalAccessKey = data.personalAccessKey;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
catch (err) {
|
|
118
|
-
(0, errorHandlers_1.debugError)(err);
|
|
119
|
-
SpinniesManager_1.default.fail('createTestAccount', {
|
|
120
|
-
text: en_1.commands.testAccount.create.polling.pakFailure,
|
|
121
|
-
});
|
|
122
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
SpinniesManager_1.default.succeed('createTestAccount', {
|
|
126
|
-
text: en_1.commands.testAccount.create.polling.success(testAccountConfig.accountName, testAccountId),
|
|
127
|
-
});
|
|
128
106
|
if (formatOutputAsJson) {
|
|
129
107
|
logger_1.uiLogger.json(jsonOutput);
|
|
130
108
|
}
|
package/lang/en.d.ts
CHANGED
|
@@ -1502,28 +1502,6 @@ ${string}`;
|
|
|
1502
1502
|
readonly app: {
|
|
1503
1503
|
readonly describe: "Commands for managing apps.";
|
|
1504
1504
|
readonly subcommands: {
|
|
1505
|
-
readonly install: {
|
|
1506
|
-
readonly describe: "Install an OAuth app into a test account.";
|
|
1507
|
-
readonly options: {
|
|
1508
|
-
readonly appUid: "The uid of the app to install";
|
|
1509
|
-
readonly projectName: "The name of the project that contains the app";
|
|
1510
|
-
};
|
|
1511
|
-
readonly positionals: {
|
|
1512
|
-
readonly testAccountId: "The id of the test account to install the app into";
|
|
1513
|
-
};
|
|
1514
|
-
readonly errors: {
|
|
1515
|
-
readonly mustSpecifyProjectName: `You must specify a project name. Use the ${string} flag to specify the project name or run this command from within a project directory.`;
|
|
1516
|
-
readonly noAppUidFound: `No app uid found. Please specify the app uid with the ${string} flag or run this command from within a project that contains an app.`;
|
|
1517
|
-
readonly appMustBeOauth: "This command only supports installing oauth apps. Please specify an app with oauth auth type.";
|
|
1518
|
-
};
|
|
1519
|
-
readonly polling: {
|
|
1520
|
-
readonly start: "Installing app...";
|
|
1521
|
-
readonly success: "App installed successfully";
|
|
1522
|
-
readonly failure: "App installation failed";
|
|
1523
|
-
readonly error: "Error installing app";
|
|
1524
|
-
};
|
|
1525
|
-
readonly example: "Install the app with uid my-app-uid from the project named \"my-project\" into the target account with id 1234567890";
|
|
1526
|
-
};
|
|
1527
1505
|
readonly secret: {
|
|
1528
1506
|
readonly describe: "Commands for managing secrets.";
|
|
1529
1507
|
readonly subcommands: {
|
|
@@ -1833,9 +1811,7 @@ ${string}`;
|
|
|
1833
1811
|
readonly start: (testAccountName: string) => string;
|
|
1834
1812
|
readonly syncing: "Test account created! Syncing account data... (may take a few minutes - you can exit and the sync will continue)";
|
|
1835
1813
|
readonly success: (testAccountName: string, testAccountId: number) => string;
|
|
1836
|
-
readonly
|
|
1837
|
-
readonly syncFailure: "Failed to sync data into test account. The account may not be ready to use.";
|
|
1838
|
-
readonly pakFailure: "Failed to generate a personal access key for the test account.";
|
|
1814
|
+
readonly failure: "Failed to sync data into test account. The account may not be ready to use.";
|
|
1839
1815
|
};
|
|
1840
1816
|
readonly options: {
|
|
1841
1817
|
readonly configPath: "The path to the test account config";
|
package/lang/en.js
CHANGED
|
@@ -1500,28 +1500,6 @@ exports.commands = {
|
|
|
1500
1500
|
app: {
|
|
1501
1501
|
describe: 'Commands for managing apps.',
|
|
1502
1502
|
subcommands: {
|
|
1503
|
-
install: {
|
|
1504
|
-
describe: 'Install an OAuth app into a test account.',
|
|
1505
|
-
options: {
|
|
1506
|
-
appUid: 'The uid of the app to install',
|
|
1507
|
-
projectName: 'The name of the project that contains the app',
|
|
1508
|
-
},
|
|
1509
|
-
positionals: {
|
|
1510
|
-
testAccountId: 'The id of the test account to install the app into',
|
|
1511
|
-
},
|
|
1512
|
-
errors: {
|
|
1513
|
-
mustSpecifyProjectName: `You must specify a project name. Use the ${(0, ui_1.uiCommandReference)('--project-name')} flag to specify the project name or run this command from within a project directory.`,
|
|
1514
|
-
noAppUidFound: `No app uid found. Please specify the app uid with the ${(0, ui_1.uiCommandReference)('--app-uid')} flag or run this command from within a project that contains an app.`,
|
|
1515
|
-
appMustBeOauth: 'This command only supports installing oauth apps. Please specify an app with oauth auth type.',
|
|
1516
|
-
},
|
|
1517
|
-
polling: {
|
|
1518
|
-
start: 'Installing app...',
|
|
1519
|
-
success: 'App installed successfully',
|
|
1520
|
-
failure: 'App installation failed',
|
|
1521
|
-
error: 'Error installing app',
|
|
1522
|
-
},
|
|
1523
|
-
example: 'Install the app with uid my-app-uid from the project named "my-project" into the target account with id 1234567890',
|
|
1524
|
-
},
|
|
1525
1503
|
secret: {
|
|
1526
1504
|
describe: 'Commands for managing secrets.',
|
|
1527
1505
|
subcommands: {
|
|
@@ -1831,9 +1809,7 @@ exports.commands = {
|
|
|
1831
1809
|
start: (testAccountName) => `Creating test account "${chalk_1.default.bold(testAccountName)}"...`,
|
|
1832
1810
|
syncing: 'Test account created! Syncing account data... (may take a few minutes - you can exit and the sync will continue)',
|
|
1833
1811
|
success: (testAccountName, testAccountId) => `Test account "${chalk_1.default.bold(testAccountName)}" successfully created with id: ${chalk_1.default.bold(testAccountId)}`,
|
|
1834
|
-
|
|
1835
|
-
syncFailure: 'Failed to sync data into test account. The account may not be ready to use.',
|
|
1836
|
-
pakFailure: 'Failed to generate a personal access key for the test account.',
|
|
1812
|
+
failure: 'Failed to sync data into test account. The account may not be ready to use.',
|
|
1837
1813
|
},
|
|
1838
1814
|
options: {
|
|
1839
1815
|
configPath: 'The path to the test account config',
|
|
@@ -2,5 +2,5 @@ export declare function installPackages({ packages, installLocations, }: {
|
|
|
2
2
|
packages?: string[];
|
|
3
3
|
installLocations?: string[];
|
|
4
4
|
}): Promise<void>;
|
|
5
|
-
export declare function getProjectPackageJsonLocations(): Promise<string[]>;
|
|
5
|
+
export declare function getProjectPackageJsonLocations(dir?: string): Promise<string[]>;
|
|
6
6
|
export declare function hasMissingPackages(directory: string): Promise<boolean>;
|
|
@@ -65,8 +65,8 @@ async function installPackagesInDirectory(directory, packages) {
|
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
async function getProjectPackageJsonLocations() {
|
|
69
|
-
const projectConfig = await (0, config_1.getProjectConfig)();
|
|
68
|
+
async function getProjectPackageJsonLocations(dir) {
|
|
69
|
+
const projectConfig = await (0, config_1.getProjectConfig)(dir);
|
|
70
70
|
if (!projectConfig ||
|
|
71
71
|
!projectConfig.projectDir ||
|
|
72
72
|
!projectConfig.projectConfig) {
|
package/lib/mcp/setup.js
CHANGED
|
@@ -157,7 +157,7 @@ async function setupClaudeCode(mcpCommand = defaultMcpCommand) {
|
|
|
157
157
|
// Run claude mcp add command
|
|
158
158
|
const mcpConfig = JSON.stringify({
|
|
159
159
|
type: 'stdio',
|
|
160
|
-
...mcpCommand,
|
|
160
|
+
...buildCommandWithAgentString(mcpCommand, claudeCode),
|
|
161
161
|
});
|
|
162
162
|
const { stdout } = await (0, command_1.execAsync)('claude mcp list');
|
|
163
163
|
if (stdout.includes(mcpServerName)) {
|
|
@@ -203,7 +203,7 @@ function setupCursor(mcpCommand = defaultMcpCommand) {
|
|
|
203
203
|
configuringMessage: en_1.commands.mcp.setup.spinners.configuringCursor,
|
|
204
204
|
configuredMessage: en_1.commands.mcp.setup.spinners.configuredCursor,
|
|
205
205
|
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureCursor,
|
|
206
|
-
mcpCommand,
|
|
206
|
+
mcpCommand: buildCommandWithAgentString(mcpCommand, cursor),
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
209
|
function setupWindsurf(mcpCommand = defaultMcpCommand) {
|
|
@@ -213,6 +213,11 @@ function setupWindsurf(mcpCommand = defaultMcpCommand) {
|
|
|
213
213
|
configuringMessage: en_1.commands.mcp.setup.spinners.configuringWindsurf,
|
|
214
214
|
configuredMessage: en_1.commands.mcp.setup.spinners.configuredWindsurf,
|
|
215
215
|
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureWindsurf,
|
|
216
|
-
mcpCommand,
|
|
216
|
+
mcpCommand: buildCommandWithAgentString(mcpCommand, windsurf),
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
|
+
function buildCommandWithAgentString(mcpCommand, agent) {
|
|
220
|
+
const mcpCommandCopy = structuredClone(mcpCommand);
|
|
221
|
+
mcpCommandCopy.args.push('--ai-agent', agent);
|
|
222
|
+
return mcpCommandCopy;
|
|
223
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentTypes, Component, GenericComponentConfig, PublicAppComponentConfig, PrivateAppComponentConfig, AppCardComponentConfig } from '../../types/Projects';
|
|
2
|
-
import {
|
|
2
|
+
import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types';
|
|
3
3
|
import { AppIRNode } from '../../types/ProjectComponents';
|
|
4
4
|
export declare const CONFIG_FILES: {
|
|
5
5
|
[k in ComponentTypes]: string;
|
|
@@ -15,4 +15,4 @@ export declare function getProjectComponentTypes(components: Array<Component>):
|
|
|
15
15
|
export declare function getComponentUid(component?: Component | null): string | null;
|
|
16
16
|
export declare function componentIsApp(component?: Component | null): component is Component<PublicAppComponentConfig | PrivateAppComponentConfig>;
|
|
17
17
|
export declare function componentIsPublicApp(component?: Component | null): component is Component<PublicAppComponentConfig>;
|
|
18
|
-
export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev
|
|
18
|
+
export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev): component is AppIRNode;
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FileResult } from 'tmp';
|
|
2
|
-
import { IntermediateRepresentation } from '@hubspot/project-parsing-lib';
|
|
3
2
|
import { ProjectConfig } from '../../types/Projects';
|
|
4
3
|
type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId: number) => Promise<T>;
|
|
5
4
|
type ProjectUploadResult<T> = {
|
|
@@ -21,5 +20,5 @@ type HandleProjectUploadArg<T> = {
|
|
|
21
20
|
export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
|
|
22
21
|
export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig): void;
|
|
23
22
|
export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
|
|
24
|
-
export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<
|
|
23
|
+
export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<unknown>;
|
|
25
24
|
export {};
|
package/lib/projects/upload.js
CHANGED
package/lib/testUtils.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mockHubSpotHttpResponse = mockHubSpotHttpResponse;
|
|
4
4
|
exports.mockHubSpotHttpError = mockHubSpotHttpError;
|
|
5
|
-
const axios_1 = require("axios");
|
|
6
5
|
const HubSpotHttpError_1 = require("@hubspot/local-dev-lib/models/HubSpotHttpError");
|
|
7
6
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
7
|
function mockHubSpotHttpResponse(data) {
|
|
@@ -12,7 +11,7 @@ function mockHubSpotHttpResponse(data) {
|
|
|
12
11
|
statusText: 'OK',
|
|
13
12
|
headers: {},
|
|
14
13
|
config: {
|
|
15
|
-
headers:
|
|
14
|
+
headers: {},
|
|
16
15
|
},
|
|
17
16
|
});
|
|
18
17
|
}
|
package/lib/usageTracking.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ type Meta = {
|
|
|
13
13
|
file?: boolean;
|
|
14
14
|
successful?: boolean;
|
|
15
15
|
};
|
|
16
|
-
export declare function trackCommandUsage(command: string, meta?: Meta, accountId?: number):
|
|
17
|
-
export declare function trackHelpUsage(command: string):
|
|
18
|
-
export declare function trackConvertFieldsUsage(command: string):
|
|
19
|
-
export declare function trackAuthAction(command: string, authType: string, step: string, accountId?: number):
|
|
20
|
-
export declare function trackCommandMetadataUsage(command: string, meta?: Meta, accountId?: number):
|
|
16
|
+
export declare function trackCommandUsage(command: string, meta?: Meta, accountId?: number): void;
|
|
17
|
+
export declare function trackHelpUsage(command: string): void;
|
|
18
|
+
export declare function trackConvertFieldsUsage(command: string): void;
|
|
19
|
+
export declare function trackAuthAction(command: string, authType: string, step: string, accountId?: number): void;
|
|
20
|
+
export declare function trackCommandMetadataUsage(command: string, meta?: Meta, accountId?: number): void;
|
|
21
21
|
export {};
|
package/lib/usageTracking.js
CHANGED
|
@@ -33,7 +33,7 @@ function getPlatform() {
|
|
|
33
33
|
return process.platform;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
function trackCommandUsage(command, meta = {}, accountId) {
|
|
37
37
|
if (!(0, config_1.isTrackingAllowed)()) {
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
@@ -46,88 +46,47 @@ async function trackCommandUsage(command, meta = {}, accountId) {
|
|
|
46
46
|
? accountConfig.authType
|
|
47
47
|
: auth_1.API_KEY_AUTH_METHOD.value;
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
command,
|
|
56
|
-
authType,
|
|
57
|
-
...meta,
|
|
58
|
-
};
|
|
59
|
-
try {
|
|
60
|
-
await (0, trackUsage_1.trackUsage)('cli-interaction', EventClass.INTERACTION, usageTrackingEvent, accountId);
|
|
61
|
-
logger_1.logger.debug('Sent usage tracking command event: %o', usageTrackingEvent);
|
|
62
|
-
}
|
|
63
|
-
catch (e) {
|
|
64
|
-
(0, errorHandlers_1.debugError)(e);
|
|
65
|
-
}
|
|
49
|
+
trackCliInteraction({
|
|
50
|
+
action: 'cli-command',
|
|
51
|
+
command,
|
|
52
|
+
authType,
|
|
53
|
+
...meta,
|
|
54
|
+
accountId,
|
|
66
55
|
});
|
|
67
56
|
}
|
|
68
|
-
|
|
57
|
+
function trackHelpUsage(command) {
|
|
69
58
|
if (!(0, config_1.isTrackingAllowed)()) {
|
|
70
59
|
return;
|
|
71
60
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
logger_1.logger.debug('Tracking help usage of "%s" sub-command', command);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
logger_1.logger.debug('Tracking help usage of main command');
|
|
78
|
-
}
|
|
79
|
-
await (0, trackUsage_1.trackUsage)('cli-interaction', EventClass.INTERACTION, {
|
|
80
|
-
action: 'cli-help',
|
|
81
|
-
os: getPlatform(),
|
|
82
|
-
...getNodeVersionData(),
|
|
83
|
-
version: package_json_1.version,
|
|
84
|
-
command,
|
|
85
|
-
});
|
|
61
|
+
if (command) {
|
|
62
|
+
logger_1.logger.debug('Tracking help usage of "%s" sub-command', command);
|
|
86
63
|
}
|
|
87
|
-
|
|
88
|
-
(
|
|
64
|
+
else {
|
|
65
|
+
logger_1.logger.debug('Tracking help usage of main command');
|
|
89
66
|
}
|
|
67
|
+
trackCliInteraction({
|
|
68
|
+
action: 'cli-help',
|
|
69
|
+
command,
|
|
70
|
+
});
|
|
90
71
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
logger_1.logger.debug('Attempting to track usage of "%s" command', command);
|
|
97
|
-
await (0, trackUsage_1.trackUsage)('cli-interaction', EventClass.INTERACTION, {
|
|
98
|
-
action: 'cli-process-fields',
|
|
99
|
-
os: getPlatform(),
|
|
100
|
-
...getNodeVersionData(),
|
|
101
|
-
version: package_json_1.version,
|
|
102
|
-
command,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
(0, errorHandlers_1.debugError)(e);
|
|
107
|
-
}
|
|
72
|
+
function trackConvertFieldsUsage(command) {
|
|
73
|
+
trackCliInteraction({
|
|
74
|
+
action: 'cli-process-fields',
|
|
75
|
+
command,
|
|
76
|
+
});
|
|
108
77
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const usageTrackingEvent = {
|
|
78
|
+
function trackAuthAction(command, authType, step, accountId) {
|
|
79
|
+
trackCliInteraction({
|
|
114
80
|
action: 'cli-auth',
|
|
115
|
-
os: getPlatform(),
|
|
116
|
-
...getNodeVersionData(),
|
|
117
|
-
version: package_json_1.version,
|
|
118
81
|
command,
|
|
119
82
|
authType,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
catch (e) {
|
|
127
|
-
(0, errorHandlers_1.debugError)(e);
|
|
128
|
-
}
|
|
83
|
+
accountId,
|
|
84
|
+
meta: {
|
|
85
|
+
step,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
129
88
|
}
|
|
130
|
-
|
|
89
|
+
function trackCommandMetadataUsage(command, meta = {}, accountId) {
|
|
131
90
|
if (!(0, config_1.isTrackingAllowed)()) {
|
|
132
91
|
return;
|
|
133
92
|
}
|
|
@@ -140,9 +99,21 @@ async function trackCommandMetadataUsage(command, meta = {}, accountId) {
|
|
|
140
99
|
? accountConfig.authType
|
|
141
100
|
: auth_1.API_KEY_AUTH_METHOD.value;
|
|
142
101
|
}
|
|
143
|
-
|
|
102
|
+
trackCliInteraction({
|
|
103
|
+
action: 'cli-command-metadata',
|
|
104
|
+
command,
|
|
105
|
+
authType,
|
|
106
|
+
accountId,
|
|
107
|
+
meta,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
function trackCliInteraction({ action, accountId, command, authType, meta = {}, }) {
|
|
111
|
+
try {
|
|
112
|
+
if (!(0, config_1.isTrackingAllowed)()) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
144
115
|
const usageTrackingEvent = {
|
|
145
|
-
action
|
|
116
|
+
action,
|
|
146
117
|
os: getPlatform(),
|
|
147
118
|
...getNodeVersionData(),
|
|
148
119
|
version: package_json_1.version,
|
|
@@ -150,12 +121,33 @@ async function trackCommandMetadataUsage(command, meta = {}, accountId) {
|
|
|
150
121
|
authType,
|
|
151
122
|
...meta,
|
|
152
123
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
124
|
+
logger_1.logger.debug('LFFFFFGGGGGG');
|
|
125
|
+
logger_1.logger.debug(process.env);
|
|
126
|
+
if (process.env.HUBSPOT_MCP_AI_AGENT) {
|
|
127
|
+
setImmediate(async () => {
|
|
128
|
+
try {
|
|
129
|
+
await (0, trackUsage_1.trackUsage)('cli-interaction', EventClass.INTERACTION, {
|
|
130
|
+
...usageTrackingEvent,
|
|
131
|
+
action: 'cli-mcp-server',
|
|
132
|
+
type: process.env.HUBSPOT_MCP_AI_AGENT,
|
|
133
|
+
}, accountId);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
(0, errorHandlers_1.debugError)(error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
156
139
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
140
|
+
setImmediate(async () => {
|
|
141
|
+
try {
|
|
142
|
+
await (0, trackUsage_1.trackUsage)('cli-interaction', EventClass.INTERACTION, usageTrackingEvent, accountId);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
(0, errorHandlers_1.debugError)(error);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
logger_1.logger.debug('Sent usage tracking command event: %o', usageTrackingEvent);
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
(0, errorHandlers_1.debugError)(e);
|
|
152
|
+
}
|
|
161
153
|
}
|
|
@@ -21,7 +21,7 @@ class UploadProjectTools extends types_1.Tool {
|
|
|
21
21
|
super(mcpServer);
|
|
22
22
|
}
|
|
23
23
|
async handler({ absoluteProjectPath, }) {
|
|
24
|
-
const { stdout, stderr } = await (0, project_1.runCommandInDir)(absoluteProjectPath, `hs project upload --force-create`);
|
|
24
|
+
const { stdout, stderr } = await (0, project_1.runCommandInDir)(absoluteProjectPath, `hs project upload --force-create --debug`);
|
|
25
25
|
return (0, content_1.formatTextContents)(stdout, stderr);
|
|
26
26
|
}
|
|
27
27
|
register() {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/cli",
|
|
3
|
-
"version": "7.7.
|
|
3
|
+
"version": "7.7.18-experimental.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",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@hubspot/local-dev-lib": "3.
|
|
8
|
+
"@hubspot/local-dev-lib": "3.12.0",
|
|
9
9
|
"@hubspot/project-parsing-lib": "0.5.1",
|
|
10
10
|
"@hubspot/serverless-dev-runtime": "7.0.6",
|
|
11
11
|
"@hubspot/theme-preview-dev-server": "0.0.10",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule, JSONOutputArgs } from '../../types/Yargs';
|
|
2
|
-
type InstallAppArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & JSONOutputArgs & {
|
|
3
|
-
appUid?: string;
|
|
4
|
-
projectName?: string;
|
|
5
|
-
testAccountId: number;
|
|
6
|
-
};
|
|
7
|
-
declare const installAppCommand: YargsCommandModule<unknown, InstallAppArgs>;
|
|
8
|
-
export default installAppCommand;
|
package/commands/app/install.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const developerTestAccounts_1 = require("@hubspot/local-dev-lib/api/developerTestAccounts");
|
|
7
|
-
const usageTracking_1 = require("../../lib/usageTracking");
|
|
8
|
-
const en_1 = require("../../lang/en");
|
|
9
|
-
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
10
|
-
const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
11
|
-
const constants_1 = require("../../lib/constants");
|
|
12
|
-
const logger_1 = require("../../lib/ui/logger");
|
|
13
|
-
const SpinniesManager_1 = __importDefault(require("../../lib/ui/SpinniesManager"));
|
|
14
|
-
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
15
|
-
const polling_1 = require("../../lib/polling");
|
|
16
|
-
const config_1 = require("../../lib/projects/config");
|
|
17
|
-
const upload_1 = require("../../lib/projects/upload");
|
|
18
|
-
const structure_1 = require("../../lib/projects/structure");
|
|
19
|
-
const command = 'install <test-account-id>';
|
|
20
|
-
const describe = undefined; // commands.app.subcommands.install.describe;
|
|
21
|
-
async function handler(args) {
|
|
22
|
-
const { derivedAccountId, appUid, projectName, testAccountId, formatOutputAsJson, } = args;
|
|
23
|
-
(0, usageTracking_1.trackCommandUsage)('app-install', {}, derivedAccountId);
|
|
24
|
-
const jsonOutput = {};
|
|
25
|
-
let targetProjectName = projectName;
|
|
26
|
-
let targetAppUid = appUid;
|
|
27
|
-
const { projectConfig, projectDir } = await (0, config_1.getProjectConfig)();
|
|
28
|
-
if (!targetProjectName) {
|
|
29
|
-
(0, config_1.validateProjectConfig)(projectConfig, projectDir);
|
|
30
|
-
targetProjectName = projectConfig?.name;
|
|
31
|
-
}
|
|
32
|
-
if (!targetProjectName) {
|
|
33
|
-
logger_1.uiLogger.error(en_1.commands.app.subcommands.install.errors.mustSpecifyProjectName);
|
|
34
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
35
|
-
}
|
|
36
|
-
let isAppOauth = true;
|
|
37
|
-
if (!targetAppUid) {
|
|
38
|
-
const intermediateRepresentation = await (0, upload_1.handleTranslate)(projectDir, projectConfig, derivedAccountId, true, undefined);
|
|
39
|
-
if (intermediateRepresentation) {
|
|
40
|
-
Object.values(intermediateRepresentation.intermediateNodesIndexedByUid).forEach(node => {
|
|
41
|
-
if ((0, structure_1.isAppIRNode)(node)) {
|
|
42
|
-
targetAppUid = node.uid;
|
|
43
|
-
isAppOauth = node.config.auth.type === constants_1.APP_AUTH_TYPES.OAUTH;
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (!targetAppUid) {
|
|
49
|
-
logger_1.uiLogger.error(en_1.commands.app.subcommands.install.errors.noAppUidFound);
|
|
50
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
51
|
-
}
|
|
52
|
-
if (!isAppOauth) {
|
|
53
|
-
logger_1.uiLogger.error(en_1.commands.app.subcommands.install.errors.appMustBeOauth);
|
|
54
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
55
|
-
}
|
|
56
|
-
try {
|
|
57
|
-
const { data } = await (0, developerTestAccounts_1.installOauthAppIntoDeveloperTestAccount)(derivedAccountId, testAccountId, targetProjectName, targetAppUid);
|
|
58
|
-
if (data?.authCodes.length > 0) {
|
|
59
|
-
jsonOutput.authCode = data.authCodes[0].authCode;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
(0, errorHandlers_1.logError)(err);
|
|
64
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
65
|
-
}
|
|
66
|
-
SpinniesManager_1.default.init({
|
|
67
|
-
succeedColor: 'white',
|
|
68
|
-
});
|
|
69
|
-
SpinniesManager_1.default.add('installApp', {
|
|
70
|
-
text: en_1.commands.app.subcommands.install.polling.start,
|
|
71
|
-
});
|
|
72
|
-
let appInstallSucceeded = false;
|
|
73
|
-
try {
|
|
74
|
-
await (0, polling_1.poll)(() => (0, developerTestAccounts_1.fetchDeveloperTestAccountOauthAppInstallStatus)(derivedAccountId, targetProjectName, targetAppUid), {
|
|
75
|
-
successStates: ['SUCCESS'],
|
|
76
|
-
errorStates: [],
|
|
77
|
-
});
|
|
78
|
-
appInstallSucceeded = true;
|
|
79
|
-
}
|
|
80
|
-
catch (err) {
|
|
81
|
-
SpinniesManager_1.default.fail('installApp');
|
|
82
|
-
(0, errorHandlers_1.logError)(err);
|
|
83
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
84
|
-
}
|
|
85
|
-
if (!appInstallSucceeded) {
|
|
86
|
-
SpinniesManager_1.default.fail('installApp');
|
|
87
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
88
|
-
}
|
|
89
|
-
SpinniesManager_1.default.succeed('installApp', {
|
|
90
|
-
text: en_1.commands.app.subcommands.install.polling.success,
|
|
91
|
-
});
|
|
92
|
-
if (formatOutputAsJson) {
|
|
93
|
-
logger_1.uiLogger.json(jsonOutput);
|
|
94
|
-
}
|
|
95
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
96
|
-
}
|
|
97
|
-
function installAppBuilder(yargs) {
|
|
98
|
-
yargs.positional('test-account-id', {
|
|
99
|
-
describe: en_1.commands.app.subcommands.install.positionals.testAccountId,
|
|
100
|
-
required: true,
|
|
101
|
-
type: 'number',
|
|
102
|
-
});
|
|
103
|
-
yargs.option('app-uid', {
|
|
104
|
-
describe: en_1.commands.app.subcommands.install.options.appUid,
|
|
105
|
-
type: 'string',
|
|
106
|
-
});
|
|
107
|
-
yargs.option('project-name', {
|
|
108
|
-
describe: en_1.commands.app.subcommands.install.options.projectName,
|
|
109
|
-
type: 'string',
|
|
110
|
-
});
|
|
111
|
-
yargs.example('install 1234567890 --app-uid=my-app-uid --project-name=my-project', en_1.commands.app.subcommands.install.example);
|
|
112
|
-
return yargs;
|
|
113
|
-
}
|
|
114
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(installAppBuilder, command, en_1.commands.app.subcommands.install.describe, {
|
|
115
|
-
useGlobalOptions: true,
|
|
116
|
-
useAccountOptions: true,
|
|
117
|
-
useConfigOptions: true,
|
|
118
|
-
useEnvironmentOptions: true,
|
|
119
|
-
useJSONOutputOptions: true,
|
|
120
|
-
});
|
|
121
|
-
const installAppCommand = {
|
|
122
|
-
command,
|
|
123
|
-
describe,
|
|
124
|
-
handler,
|
|
125
|
-
builder,
|
|
126
|
-
};
|
|
127
|
-
exports.default = installAppCommand;
|