@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.
- package/bin/cli.js +4 -0
- package/bin/hs +1 -1
- package/commands/getStarted.d.ts +9 -0
- package/commands/getStarted.js +227 -0
- package/commands/init.js +6 -1
- package/commands/mcp/setup.d.ts +4 -10
- package/commands/mcp/setup.js +28 -220
- package/commands/mcp/start.d.ts +3 -9
- package/commands/mcp/start.js +18 -15
- package/commands/mcp.js +2 -1
- package/commands/project/deploy.d.ts +1 -0
- package/commands/project/deploy.js +29 -3
- package/commands/project/upload.d.ts +2 -2
- package/commands/project/upload.js +18 -23
- package/commands/project/validate.d.ts +6 -0
- package/commands/project/validate.js +82 -0
- package/commands/project.js +2 -0
- package/commands/testAccount/create.d.ts +6 -0
- package/commands/testAccount/create.js +110 -0
- package/commands/testAccount/createConfig.d.ts +10 -0
- package/commands/testAccount/createConfig.js +98 -0
- package/commands/testAccount/delete.d.ts +6 -0
- package/commands/testAccount/delete.js +48 -0
- package/commands/testAccount.d.ts +3 -0
- package/commands/testAccount.js +28 -0
- package/lang/en.d.ts +144 -29
- package/lang/en.js +144 -32
- package/lang/en.lyaml +9 -14
- package/lib/app/migrate.js +15 -3
- package/lib/commonOpts.d.ts +2 -0
- package/lib/commonOpts.js +21 -9
- package/lib/constants.d.ts +5 -0
- package/lib/constants.js +6 -1
- package/lib/doctor/Doctor.js +1 -1
- package/lib/errorHandlers/index.js +7 -0
- package/lib/mcp/setup.d.ts +21 -0
- package/lib/mcp/setup.js +218 -0
- package/lib/projectProfiles.d.ts +1 -0
- package/lib/projectProfiles.js +18 -0
- package/lib/projects/buildAndDeploy.js +1 -1
- package/lib/projects/localDev/AppDevModeInterface.d.ts +3 -0
- package/lib/projects/localDev/AppDevModeInterface.js +45 -16
- package/lib/projects/localDev/LocalDevManager.js +1 -1
- package/lib/projects/upload.d.ts +3 -0
- package/lib/projects/upload.js +56 -22
- package/lib/projects/urls.d.ts +2 -0
- package/lib/projects/urls.js +10 -0
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.d.ts +17 -0
- package/lib/prompts/createDeveloperTestAccountConfigPrompt.js +96 -0
- package/lib/prompts/installAppPrompt.d.ts +2 -1
- package/lib/prompts/installAppPrompt.js +12 -2
- package/lib/prompts/promptUtils.d.ts +1 -0
- package/lib/prompts/promptUtils.js +2 -0
- package/lib/ui/logger.d.ts +1 -0
- package/lib/ui/logger.js +1 -0
- package/lib/yargsUtils.d.ts +1 -0
- package/lib/yargsUtils.js +3 -0
- package/mcp-server/tools/index.js +2 -0
- package/mcp-server/tools/project/AddFeatureToProject.js +6 -29
- package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/CreateProjectTool.js +12 -31
- package/mcp-server/tools/project/DeployProject.js +4 -11
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +3 -16
- package/mcp-server/tools/project/UploadProjectTools.js +3 -7
- package/mcp-server/tools/project/ValidateProjectTool.d.ts +17 -0
- package/mcp-server/tools/project/ValidateProjectTool.js +35 -0
- package/mcp-server/utils/content.d.ts +3 -0
- package/mcp-server/utils/content.js +21 -0
- package/package.json +10 -9
- package/types/LocalDev.d.ts +1 -0
- package/types/Yargs.d.ts +4 -0
package/bin/cli.js
CHANGED
|
@@ -44,6 +44,8 @@ const feedback_1 = __importDefault(require("../commands/feedback"));
|
|
|
44
44
|
const doctor_1 = __importDefault(require("../commands/doctor"));
|
|
45
45
|
const completion_1 = __importDefault(require("../commands/completion"));
|
|
46
46
|
const app_1 = __importDefault(require("../commands/app"));
|
|
47
|
+
const testAccount_1 = __importDefault(require("../commands/testAccount"));
|
|
48
|
+
const getStarted_1 = __importDefault(require("../commands/getStarted"));
|
|
47
49
|
const mcp_1 = __importDefault(require("../commands/mcp"));
|
|
48
50
|
function getTerminalWidth() {
|
|
49
51
|
const width = yargs_1.default.terminalWidth();
|
|
@@ -123,6 +125,8 @@ const argv = yargs_1.default
|
|
|
123
125
|
.command(doctor_1.default)
|
|
124
126
|
.command(completion_1.default)
|
|
125
127
|
.command(app_1.default)
|
|
128
|
+
.command(testAccount_1.default)
|
|
129
|
+
.command(getStarted_1.default)
|
|
126
130
|
.command(mcp_1.default)
|
|
127
131
|
.help()
|
|
128
132
|
.alias('h', 'help')
|
package/bin/hs
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AccountArgs, YargsCommandModule, CommonArgs, ConfigArgs, EnvironmentArgs } from '../types/Yargs';
|
|
2
|
+
export declare const command = "get-started";
|
|
3
|
+
export declare const describe: undefined;
|
|
4
|
+
type GetStartedArgs = CommonArgs & ConfigArgs & AccountArgs & EnvironmentArgs & {
|
|
5
|
+
name?: string;
|
|
6
|
+
dest?: string;
|
|
7
|
+
};
|
|
8
|
+
declare const getStartedCommand: YargsCommandModule<unknown, GetStartedArgs>;
|
|
9
|
+
export default getStartedCommand;
|
|
@@ -0,0 +1,227 @@
|
|
|
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
|
+
exports.describe = exports.command = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const open_1 = __importDefault(require("open"));
|
|
10
|
+
const path_2 = require("@hubspot/local-dev-lib/path");
|
|
11
|
+
const github_1 = require("@hubspot/local-dev-lib/github");
|
|
12
|
+
const en_1 = require("../lang/en");
|
|
13
|
+
const usageTracking_1 = require("../lib/usageTracking");
|
|
14
|
+
const exitCodes_1 = require("../lib/enums/exitCodes");
|
|
15
|
+
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
16
|
+
const promptUtils_1 = require("../lib/prompts/promptUtils");
|
|
17
|
+
const createProjectPrompt_1 = require("../lib/prompts/createProjectPrompt");
|
|
18
|
+
const ui_1 = require("../lib/ui");
|
|
19
|
+
const logger_1 = require("../lib/ui/logger");
|
|
20
|
+
const errorHandlers_1 = require("../lib/errorHandlers");
|
|
21
|
+
const upload_1 = require("../lib/projects/upload");
|
|
22
|
+
const constants_1 = require("../lib/constants");
|
|
23
|
+
const config_1 = require("../lib/projects/config");
|
|
24
|
+
const buildAndDeploy_1 = require("../lib/projects/buildAndDeploy");
|
|
25
|
+
const urls_1 = require("../lib/projects/urls");
|
|
26
|
+
const links_1 = require("../lib/links");
|
|
27
|
+
exports.command = 'get-started';
|
|
28
|
+
exports.describe = undefined;
|
|
29
|
+
async function handler(args) {
|
|
30
|
+
const { derivedAccountId } = args;
|
|
31
|
+
// TODO: Put this in constants.ts once we have a defined place for the template before INBOUND
|
|
32
|
+
const templateSource = 'robrown-hubspot/hubspot-project-components-ua-app-objects-beta';
|
|
33
|
+
(0, usageTracking_1.trackCommandUsage)('get-started', {}, derivedAccountId);
|
|
34
|
+
(0, ui_1.uiInfoSection)(en_1.commands.getStarted.startTitle, () => {
|
|
35
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.startDescription);
|
|
36
|
+
});
|
|
37
|
+
const { default: selectedOption } = await (0, promptUtils_1.promptUser)([
|
|
38
|
+
{
|
|
39
|
+
type: 'list',
|
|
40
|
+
name: 'default',
|
|
41
|
+
message: en_1.commands.getStarted.prompts.selectOption,
|
|
42
|
+
choices: [
|
|
43
|
+
{
|
|
44
|
+
name: en_1.commands.getStarted.prompts.options.app,
|
|
45
|
+
value: constants_1.GET_STARTED_OPTIONS.APP,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: en_1.commands.getStarted.prompts.options.cms,
|
|
49
|
+
value: constants_1.GET_STARTED_OPTIONS.CMS,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
default: constants_1.GET_STARTED_OPTIONS.APP,
|
|
53
|
+
},
|
|
54
|
+
]);
|
|
55
|
+
if (selectedOption === constants_1.GET_STARTED_OPTIONS.CMS) {
|
|
56
|
+
logger_1.uiLogger.log(' ');
|
|
57
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.designManager);
|
|
58
|
+
if (process.env.BROWSER !== 'none') {
|
|
59
|
+
logger_1.uiLogger.log(' ');
|
|
60
|
+
const { shouldOpen } = await (0, promptUtils_1.promptUser)([
|
|
61
|
+
{
|
|
62
|
+
name: 'shouldOpen',
|
|
63
|
+
type: 'confirm',
|
|
64
|
+
message: en_1.commands.getStarted.openDesignManagerPrompt,
|
|
65
|
+
},
|
|
66
|
+
]);
|
|
67
|
+
if (shouldOpen) {
|
|
68
|
+
logger_1.uiLogger.log('');
|
|
69
|
+
(0, links_1.openLink)(derivedAccountId, 'design-manager');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
logger_1.uiLogger.log(' ');
|
|
76
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.prompts.appSelected);
|
|
77
|
+
// 1. Fetch project templates
|
|
78
|
+
let latestRepoReleaseTag;
|
|
79
|
+
const { dest, name } = await (0, createProjectPrompt_1.createProjectPrompt)(args);
|
|
80
|
+
// Specific template for get-started command
|
|
81
|
+
const projectTemplate = {
|
|
82
|
+
name: 'private-app-get-started-template',
|
|
83
|
+
label: 'CRM getting started project with private apps',
|
|
84
|
+
path: 'projects/private-app-get-started-template',
|
|
85
|
+
};
|
|
86
|
+
// 3. Create the project files
|
|
87
|
+
const projectDest = path_1.default.resolve((0, path_2.getCwd)(), dest);
|
|
88
|
+
const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await (0, config_1.getProjectConfig)(projectDest);
|
|
89
|
+
if (existingProjectConfig &&
|
|
90
|
+
existingProjectDir &&
|
|
91
|
+
projectDest.startsWith(existingProjectDir)) {
|
|
92
|
+
logger_1.uiLogger.log(' ');
|
|
93
|
+
logger_1.uiLogger.error(en_1.commands.project.create.errors.cannotNestProjects(existingProjectDir));
|
|
94
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
95
|
+
}
|
|
96
|
+
const repo = templateSource || constants_1.HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
97
|
+
// 4. Clone the project template from GitHub
|
|
98
|
+
// This is temporary until we have the UA template in the main repo
|
|
99
|
+
try {
|
|
100
|
+
await (0, github_1.cloneGithubRepo)(repo, projectDest, {
|
|
101
|
+
sourceDir: projectTemplate.path,
|
|
102
|
+
tag: latestRepoReleaseTag,
|
|
103
|
+
hideLogs: true,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
(0, errorHandlers_1.debugError)(err);
|
|
108
|
+
logger_1.uiLogger.log(' ');
|
|
109
|
+
logger_1.uiLogger.error(en_1.commands.project.create.errors.failedToDownloadProject);
|
|
110
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
111
|
+
}
|
|
112
|
+
const projectConfigPath = path_1.default.join(projectDest, constants_1.PROJECT_CONFIG_FILE);
|
|
113
|
+
const parsedConfigFile = JSON.parse(fs_extra_1.default.readFileSync(projectConfigPath).toString());
|
|
114
|
+
(0, config_1.writeProjectConfig)(projectConfigPath, {
|
|
115
|
+
...parsedConfigFile,
|
|
116
|
+
name,
|
|
117
|
+
});
|
|
118
|
+
logger_1.uiLogger.log(' ');
|
|
119
|
+
logger_1.uiLogger.success(en_1.commands.project.create.logs.success(name, projectDest));
|
|
120
|
+
logger_1.uiLogger.log(' ');
|
|
121
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.prompts.projectCreated.title);
|
|
122
|
+
logger_1.uiLogger.log(' ');
|
|
123
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.prompts.projectCreated.description);
|
|
124
|
+
logger_1.uiLogger.log(' ');
|
|
125
|
+
// 5. Ask user if they want to upload the project
|
|
126
|
+
const { shouldUpload } = await (0, promptUtils_1.promptUser)([
|
|
127
|
+
{
|
|
128
|
+
type: 'confirm',
|
|
129
|
+
name: 'shouldUpload',
|
|
130
|
+
message: en_1.commands.getStarted.prompts.uploadProject,
|
|
131
|
+
default: true,
|
|
132
|
+
},
|
|
133
|
+
]);
|
|
134
|
+
if (shouldUpload) {
|
|
135
|
+
try {
|
|
136
|
+
// Get the project config for the newly created project
|
|
137
|
+
const { projectConfig: newProjectConfig, projectDir: newProjectDir } = await (0, config_1.getProjectConfig)(projectDest);
|
|
138
|
+
if (!newProjectConfig || !newProjectDir) {
|
|
139
|
+
logger_1.uiLogger.log(' ');
|
|
140
|
+
logger_1.uiLogger.error(en_1.commands.getStarted.errors.configFileNotFound);
|
|
141
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
142
|
+
}
|
|
143
|
+
(0, config_1.validateProjectConfig)(newProjectConfig, newProjectDir);
|
|
144
|
+
const targetAccountId = derivedAccountId;
|
|
145
|
+
logger_1.uiLogger.log(' ');
|
|
146
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.logs.uploadingProject);
|
|
147
|
+
logger_1.uiLogger.log(' ');
|
|
148
|
+
const { result, uploadError } = await (0, upload_1.handleProjectUpload)({
|
|
149
|
+
accountId: targetAccountId,
|
|
150
|
+
projectConfig: newProjectConfig,
|
|
151
|
+
projectDir: newProjectDir,
|
|
152
|
+
callbackFunc: buildAndDeploy_1.pollProjectBuildAndDeploy,
|
|
153
|
+
uploadMessage: 'Initial upload from get-started command',
|
|
154
|
+
forceCreate: true, // Auto-create project on HubSpot
|
|
155
|
+
isUploadCommand: false,
|
|
156
|
+
sendIR: (0, buildAndDeploy_1.useV3Api)(newProjectConfig.platformVersion),
|
|
157
|
+
skipValidation: false,
|
|
158
|
+
});
|
|
159
|
+
if (uploadError) {
|
|
160
|
+
logger_1.uiLogger.log(' ');
|
|
161
|
+
logger_1.uiLogger.error(en_1.commands.getStarted.errors.uploadFailed);
|
|
162
|
+
(0, errorHandlers_1.debugError)(uploadError);
|
|
163
|
+
}
|
|
164
|
+
else if (result) {
|
|
165
|
+
logger_1.uiLogger.log(' ');
|
|
166
|
+
logger_1.uiLogger.success(en_1.commands.getStarted.logs.uploadSuccess);
|
|
167
|
+
if (process.env.BROWSER !== 'none') {
|
|
168
|
+
logger_1.uiLogger.log(' ');
|
|
169
|
+
logger_1.uiLogger.log(en_1.commands.getStarted.developerOverviewBrowserOpenPrep);
|
|
170
|
+
logger_1.uiLogger.log(' ');
|
|
171
|
+
const { shouldOpenOverview } = await (0, promptUtils_1.promptUser)([
|
|
172
|
+
{
|
|
173
|
+
name: 'shouldOpenOverview',
|
|
174
|
+
type: 'confirm',
|
|
175
|
+
message: en_1.commands.getStarted.openDeveloperOverviewPrompt,
|
|
176
|
+
},
|
|
177
|
+
]);
|
|
178
|
+
if (shouldOpenOverview) {
|
|
179
|
+
(0, open_1.default)((0, urls_1.getProjectComponentDistributionUrl)(name, 'get_started_app', derivedAccountId), { url: true });
|
|
180
|
+
logger_1.uiLogger.log(' ');
|
|
181
|
+
logger_1.uiLogger.success(en_1.commands.getStarted.openedDeveloperOverview);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
logger_1.uiLogger.log(' ');
|
|
185
|
+
(0, ui_1.uiFeatureHighlight)(['projectDevCommand']);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
logger_1.uiLogger.log(' ');
|
|
190
|
+
logger_1.uiLogger.error(en_1.commands.getStarted.errors.uploadFailed);
|
|
191
|
+
(0, errorHandlers_1.debugError)(err);
|
|
192
|
+
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
197
|
+
}
|
|
198
|
+
function getStartedBuilder(yargs) {
|
|
199
|
+
yargs.options({
|
|
200
|
+
name: {
|
|
201
|
+
describe: en_1.commands.getStarted.options.name.describe,
|
|
202
|
+
type: 'string',
|
|
203
|
+
},
|
|
204
|
+
dest: {
|
|
205
|
+
describe: en_1.commands.getStarted.options.dest.describe,
|
|
206
|
+
type: 'string',
|
|
207
|
+
},
|
|
208
|
+
'template-source': {
|
|
209
|
+
describe: en_1.commands.getStarted.options.templateSource.describe,
|
|
210
|
+
type: 'string',
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
return yargs;
|
|
214
|
+
}
|
|
215
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(getStartedBuilder, exports.command, en_1.commands.getStarted.verboseDescribe, {
|
|
216
|
+
useGlobalOptions: true,
|
|
217
|
+
useAccountOptions: true,
|
|
218
|
+
useConfigOptions: true,
|
|
219
|
+
useEnvironmentOptions: true,
|
|
220
|
+
});
|
|
221
|
+
const getStartedCommand = {
|
|
222
|
+
command: exports.command,
|
|
223
|
+
describe: exports.describe,
|
|
224
|
+
handler,
|
|
225
|
+
builder,
|
|
226
|
+
};
|
|
227
|
+
exports.default = getStartedCommand;
|
package/commands/init.js
CHANGED
|
@@ -132,7 +132,12 @@ async function handler(args) {
|
|
|
132
132
|
authType: AUTH_TYPE_NAMES[authType],
|
|
133
133
|
account: name || accountId,
|
|
134
134
|
}));
|
|
135
|
-
(0, ui_1.uiFeatureHighlight)([
|
|
135
|
+
(0, ui_1.uiFeatureHighlight)([
|
|
136
|
+
'getStartedCommand',
|
|
137
|
+
'helpCommand',
|
|
138
|
+
'authCommand',
|
|
139
|
+
'accountsListCommand',
|
|
140
|
+
]);
|
|
136
141
|
if (!disableTracking) {
|
|
137
142
|
await (0, usageTracking_1.trackAuthAction)('init', authType, TRACKING_STATUS.COMPLETE, accountId);
|
|
138
143
|
}
|
package/commands/mcp/setup.d.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
interface MCPSetupArgs {
|
|
1
|
+
import { CommonArgs, YargsCommandModule } from '../../types/Yargs';
|
|
2
|
+
interface MCPSetupArgs extends CommonArgs {
|
|
3
3
|
client?: string[];
|
|
4
4
|
addDocsSearch?: boolean;
|
|
5
5
|
}
|
|
6
|
-
declare
|
|
7
|
-
|
|
8
|
-
command: string[];
|
|
9
|
-
describe: undefined;
|
|
10
|
-
builder: (yargs: Argv) => Promise<Argv<{}>>;
|
|
11
|
-
handler: typeof handler;
|
|
12
|
-
};
|
|
13
|
-
export default _default;
|
|
6
|
+
declare const mcpSetupCommand: YargsCommandModule<unknown, MCPSetupArgs>;
|
|
7
|
+
export default mcpSetupCommand;
|
package/commands/mcp/setup.js
CHANGED
|
@@ -1,50 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const child_process_1 = require("child_process");
|
|
7
|
-
const util_1 = require("util");
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const os_1 = __importDefault(require("os"));
|
|
11
|
-
const SpinniesManager_1 = __importDefault(require("../../lib/ui/SpinniesManager"));
|
|
12
3
|
const exitCodes_1 = require("../../lib/enums/exitCodes");
|
|
13
|
-
const promptUtils_1 = require("../../lib/prompts/promptUtils");
|
|
14
4
|
const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
15
5
|
const en_1 = require("../../lang/en");
|
|
16
|
-
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
17
6
|
const logger_1 = require("../../lib/ui/logger");
|
|
7
|
+
const setup_1 = require("../../lib/mcp/setup");
|
|
8
|
+
const usageTracking_1 = require("../../lib/usageTracking");
|
|
18
9
|
const command = ['setup', 'update'];
|
|
19
10
|
const describe = undefined; // Leave hidden for now
|
|
20
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
21
|
-
const claudeCode = 'claude';
|
|
22
|
-
const windsurf = 'windsurf';
|
|
23
|
-
const cursor = 'cursor';
|
|
24
|
-
const mcpServerName = 'hubspot-cli-mcp';
|
|
25
|
-
const supportedMintlifyClients = [windsurf, cursor];
|
|
26
|
-
const supportedTools = [
|
|
27
|
-
{ name: en_1.commands.mcp.setup.claudeCode, value: claudeCode },
|
|
28
|
-
{ name: en_1.commands.mcp.setup.cursor, value: cursor },
|
|
29
|
-
{ name: en_1.commands.mcp.setup.windsurf, value: windsurf },
|
|
30
|
-
];
|
|
31
|
-
const hsCommand = 'hs';
|
|
32
|
-
const mcpCommandArgs = ['mcp', 'start'];
|
|
33
|
-
function setupBuilder(yargs) {
|
|
34
|
-
yargs
|
|
35
|
-
.option('client', {
|
|
36
|
-
describe: en_1.commands.mcp.setup.args.client,
|
|
37
|
-
type: 'array',
|
|
38
|
-
choices: [...supportedTools.map(tool => tool.value)],
|
|
39
|
-
})
|
|
40
|
-
.option('add-docs-search', {
|
|
41
|
-
type: 'boolean',
|
|
42
|
-
});
|
|
43
|
-
return yargs;
|
|
44
|
-
}
|
|
45
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(setupBuilder, command, describe, {
|
|
46
|
-
useGlobalOptions: true,
|
|
47
|
-
});
|
|
48
11
|
async function handler(args) {
|
|
49
12
|
try {
|
|
50
13
|
await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
@@ -53,192 +16,37 @@ async function handler(args) {
|
|
|
53
16
|
logger_1.uiLogger.error(en_1.commands.mcp.setup.errors.needsNode20);
|
|
54
17
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
55
18
|
}
|
|
56
|
-
|
|
57
|
-
if (args.addDocsSearch) {
|
|
58
|
-
logger_1.uiLogger.info(en_1.commands.mcp.setup.installingDocSearch);
|
|
59
|
-
logger_1.uiLogger.log('');
|
|
60
|
-
await new Promise(() => {
|
|
61
|
-
const subcommands = ['mint-mcp', 'add', 'hubspot-migration'];
|
|
62
|
-
const docsSearchClients = derivedTargets.filter(target => supportedMintlifyClients.includes(target));
|
|
63
|
-
const childProcess = (0, child_process_1.spawn)(`npx`, docsSearchClients && docsSearchClients.length
|
|
64
|
-
? [...subcommands, '--client', ...docsSearchClients]
|
|
65
|
-
: subcommands, {
|
|
66
|
-
stdio: 'inherit',
|
|
67
|
-
});
|
|
68
|
-
childProcess.on('exit', code => {
|
|
69
|
-
if (code !== 0) {
|
|
70
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
71
|
-
}
|
|
72
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
77
|
-
}
|
|
78
|
-
async function addMcpServerToConfig(targets) {
|
|
19
|
+
(0, usageTracking_1.trackCommandUsage)('mcp-setup', {}, args.derivedAccountId);
|
|
79
20
|
try {
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
name: 'selectedTargets',
|
|
84
|
-
type: 'checkbox',
|
|
85
|
-
message: en_1.commands.mcp.setup.prompts.targets,
|
|
86
|
-
choices: supportedTools,
|
|
87
|
-
validate: (choices) => {
|
|
88
|
-
return choices.length === 0
|
|
89
|
-
? en_1.commands.mcp.setup.prompts.targetsRequired
|
|
90
|
-
: true;
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
derivedTargets = selectedTargets;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
derivedTargets = targets;
|
|
97
|
-
}
|
|
98
|
-
SpinniesManager_1.default.init();
|
|
99
|
-
if (derivedTargets.includes(claudeCode)) {
|
|
100
|
-
await runSetupFunction(setupClaudeCode);
|
|
101
|
-
}
|
|
102
|
-
if (derivedTargets.includes(cursor)) {
|
|
103
|
-
await runSetupFunction(setupCursor);
|
|
21
|
+
const derivedTargets = await (0, setup_1.addMcpServerToConfig)(args.client);
|
|
22
|
+
if (args.addDocsSearch) {
|
|
23
|
+
await (0, setup_1.addMintlifyMcpServer)(derivedTargets);
|
|
104
24
|
}
|
|
105
|
-
if (derivedTargets.includes(windsurf)) {
|
|
106
|
-
await runSetupFunction(setupWindsurf);
|
|
107
|
-
}
|
|
108
|
-
logger_1.uiLogger.info(en_1.commands.mcp.setup.success(derivedTargets));
|
|
109
|
-
return derivedTargets;
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
SpinniesManager_1.default.fail('mcpSetup', {
|
|
113
|
-
text: en_1.commands.mcp.setup.spinners.failedToConfigure,
|
|
114
|
-
});
|
|
115
|
-
(0, errorHandlers_1.logError)(error);
|
|
116
|
-
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
117
25
|
}
|
|
118
|
-
|
|
119
|
-
async function runSetupFunction(func) {
|
|
120
|
-
const result = await func();
|
|
121
|
-
if (!result) {
|
|
26
|
+
catch (e) {
|
|
122
27
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
123
28
|
}
|
|
29
|
+
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
124
30
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
let mcpConfig = {};
|
|
138
|
-
try {
|
|
139
|
-
const configContent = fs_1.default.readFileSync(config.configPath, 'utf8');
|
|
140
|
-
mcpConfig = JSON.parse(configContent);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
SpinniesManager_1.default.fail('spinner', {
|
|
144
|
-
text: config.failedMessage,
|
|
145
|
-
});
|
|
146
|
-
(0, errorHandlers_1.logError)(error);
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
// Initialize mcpServers if it doesn't exist
|
|
150
|
-
if (!mcpConfig.mcpServers) {
|
|
151
|
-
mcpConfig.mcpServers = {};
|
|
152
|
-
}
|
|
153
|
-
// Add or update HubSpot CLI MCP server
|
|
154
|
-
mcpConfig.mcpServers[mcpServerName] = {
|
|
155
|
-
command: hsCommand,
|
|
156
|
-
args: mcpCommandArgs,
|
|
157
|
-
};
|
|
158
|
-
// Write the updated config
|
|
159
|
-
fs_1.default.writeFileSync(config.configPath, JSON.stringify(mcpConfig, null, 2));
|
|
160
|
-
SpinniesManager_1.default.succeed('spinner', {
|
|
161
|
-
text: config.configuredMessage,
|
|
162
|
-
});
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
SpinniesManager_1.default.fail('spinner', {
|
|
167
|
-
text: config.failedMessage,
|
|
168
|
-
});
|
|
169
|
-
(0, errorHandlers_1.logError)(error);
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async function setupClaudeCode() {
|
|
174
|
-
try {
|
|
175
|
-
SpinniesManager_1.default.add('claudeCode', {
|
|
176
|
-
text: en_1.commands.mcp.setup.spinners.configuringClaudeCode,
|
|
177
|
-
});
|
|
178
|
-
try {
|
|
179
|
-
// Check if claude command is available
|
|
180
|
-
await execAsync('claude --version');
|
|
181
|
-
// Run claude mcp add command
|
|
182
|
-
const mcpConfig = JSON.stringify({
|
|
183
|
-
type: 'stdio',
|
|
184
|
-
command: hsCommand,
|
|
185
|
-
args: mcpCommandArgs,
|
|
186
|
-
});
|
|
187
|
-
const { stdout } = await execAsync('claude mcp list');
|
|
188
|
-
if (stdout.includes(mcpServerName)) {
|
|
189
|
-
SpinniesManager_1.default.update('claudeCode', {
|
|
190
|
-
text: en_1.commands.mcp.setup.spinners.alreadyInstalled,
|
|
191
|
-
});
|
|
192
|
-
await execAsync(`claude mcp remove "${mcpServerName}" --scope user`);
|
|
193
|
-
}
|
|
194
|
-
await execAsync(`claude mcp add-json "${mcpServerName}" '${mcpConfig}' --scope user`);
|
|
195
|
-
SpinniesManager_1.default.succeed('claudeCode', {
|
|
196
|
-
text: en_1.commands.mcp.setup.spinners.configuredClaudeCode,
|
|
197
|
-
});
|
|
198
|
-
return true;
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
if (error instanceof Error &&
|
|
202
|
-
error.message.includes('claude: command not found')) {
|
|
203
|
-
SpinniesManager_1.default.fail('claudeCode', {
|
|
204
|
-
text: en_1.commands.mcp.setup.spinners.claudeCodeNotFound,
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
SpinniesManager_1.default.fail('claudeCode', {
|
|
209
|
-
text: en_1.commands.mcp.setup.spinners.claudeCodeInstallFailed,
|
|
210
|
-
});
|
|
211
|
-
(0, errorHandlers_1.logError)(error);
|
|
212
|
-
}
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
catch (error) {
|
|
217
|
-
SpinniesManager_1.default.fail('claudeCode', {
|
|
218
|
-
text: en_1.commands.mcp.setup.spinners.claudeCodeInstallFailed,
|
|
219
|
-
});
|
|
220
|
-
(0, errorHandlers_1.logError)(error);
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
function setupCursor() {
|
|
225
|
-
const cursorConfigPath = path_1.default.join(os_1.default.homedir(), '.cursor', 'mcp.json');
|
|
226
|
-
return setupMcpConfigFile({
|
|
227
|
-
configPath: cursorConfigPath,
|
|
228
|
-
configuringMessage: en_1.commands.mcp.setup.spinners.configuringCursor,
|
|
229
|
-
configuredMessage: en_1.commands.mcp.setup.spinners.configuredCursor,
|
|
230
|
-
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureCursor,
|
|
231
|
-
configMissingMessage: en_1.commands.mcp.setup.spinners.noCursorMcpFile(cursorConfigPath),
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
function setupWindsurf() {
|
|
235
|
-
const windsurfConfigPath = path_1.default.join(os_1.default.homedir(), '.codeium', 'windsurf', 'mcp_config.json');
|
|
236
|
-
return setupMcpConfigFile({
|
|
237
|
-
configPath: windsurfConfigPath,
|
|
238
|
-
configuringMessage: en_1.commands.mcp.setup.spinners.configuringWindsurf,
|
|
239
|
-
configuredMessage: en_1.commands.mcp.setup.spinners.configuredWindsurf,
|
|
240
|
-
failedMessage: en_1.commands.mcp.setup.spinners.failedToConfigureWindsurf,
|
|
241
|
-
configMissingMessage: en_1.commands.mcp.setup.spinners.noWindsurfFile(windsurfConfigPath),
|
|
31
|
+
function setupBuilder(yargs) {
|
|
32
|
+
yargs
|
|
33
|
+
.option('client', {
|
|
34
|
+
describe: en_1.commands.mcp.setup.args.client,
|
|
35
|
+
type: 'array',
|
|
36
|
+
choices: [...setup_1.supportedTools.map(tool => tool.value)],
|
|
37
|
+
})
|
|
38
|
+
.option('add-docs-search', {
|
|
39
|
+
type: 'boolean',
|
|
242
40
|
});
|
|
41
|
+
return yargs;
|
|
243
42
|
}
|
|
244
|
-
|
|
43
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(setupBuilder, command, describe, {
|
|
44
|
+
useGlobalOptions: true,
|
|
45
|
+
});
|
|
46
|
+
const mcpSetupCommand = {
|
|
47
|
+
command,
|
|
48
|
+
describe,
|
|
49
|
+
handler,
|
|
50
|
+
builder,
|
|
51
|
+
};
|
|
52
|
+
exports.default = mcpSetupCommand;
|
package/commands/mcp/start.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare
|
|
3
|
-
|
|
4
|
-
command: string;
|
|
5
|
-
describe: undefined;
|
|
6
|
-
builder: (yargs: Argv) => Promise<Argv<{}>>;
|
|
7
|
-
handler: typeof handler;
|
|
8
|
-
};
|
|
9
|
-
export default _default;
|
|
1
|
+
import { CommonArgs, YargsCommandModule } from '../../types/Yargs';
|
|
2
|
+
declare const mcpStartCommand: YargsCommandModule<unknown, CommonArgs>;
|
|
3
|
+
export default mcpStartCommand;
|
package/commands/mcp/start.js
CHANGED
|
@@ -11,15 +11,11 @@ const yargsUtils_1 = require("../../lib/yargsUtils");
|
|
|
11
11
|
const logger_1 = require("../../lib/ui/logger");
|
|
12
12
|
const errorHandlers_1 = require("../../lib/errorHandlers");
|
|
13
13
|
const en_1 = require("../../lang/en");
|
|
14
|
+
const process_1 = require("../../lib/process");
|
|
15
|
+
const usageTracking_1 = require("../../lib/usageTracking");
|
|
14
16
|
const command = 'start';
|
|
15
17
|
const describe = undefined; // Leave hidden for now
|
|
16
|
-
function
|
|
17
|
-
return yargs;
|
|
18
|
-
}
|
|
19
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(startBuilder, command, describe, {
|
|
20
|
-
useGlobalOptions: true,
|
|
21
|
-
});
|
|
22
|
-
async function handler() {
|
|
18
|
+
async function handler(args) {
|
|
23
19
|
try {
|
|
24
20
|
await import('@modelcontextprotocol/sdk/server/mcp.js');
|
|
25
21
|
}
|
|
@@ -27,6 +23,7 @@ async function handler() {
|
|
|
27
23
|
logger_1.uiLogger.error(en_1.commands.mcp.start.errors.needsNode20);
|
|
28
24
|
process.exit(exitCodes_1.EXIT_CODES.ERROR);
|
|
29
25
|
}
|
|
26
|
+
(0, usageTracking_1.trackCommandUsage)('mcp-start', {}, args.derivedAccountId);
|
|
30
27
|
await startMcpServer();
|
|
31
28
|
}
|
|
32
29
|
async function startMcpServer() {
|
|
@@ -54,13 +51,7 @@ async function startMcpServer() {
|
|
|
54
51
|
child.on('close', () => {
|
|
55
52
|
logger_1.uiLogger.info(en_1.commands.mcp.start.stoppedSuccessfully);
|
|
56
53
|
});
|
|
57
|
-
|
|
58
|
-
process.on('SIGINT', () => {
|
|
59
|
-
logger_1.uiLogger.info(en_1.commands.mcp.start.shuttingDown);
|
|
60
|
-
child.kill('SIGTERM');
|
|
61
|
-
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
62
|
-
});
|
|
63
|
-
process.on('SIGTERM', () => {
|
|
54
|
+
(0, process_1.handleExit)(() => {
|
|
64
55
|
logger_1.uiLogger.info(en_1.commands.mcp.start.shuttingDown);
|
|
65
56
|
child.kill('SIGTERM');
|
|
66
57
|
process.exit(exitCodes_1.EXIT_CODES.SUCCESS);
|
|
@@ -71,4 +62,16 @@ async function startMcpServer() {
|
|
|
71
62
|
(0, errorHandlers_1.logError)(error);
|
|
72
63
|
}
|
|
73
64
|
}
|
|
74
|
-
|
|
65
|
+
function startBuilder(yargs) {
|
|
66
|
+
return yargs;
|
|
67
|
+
}
|
|
68
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(startBuilder, command, describe, {
|
|
69
|
+
useGlobalOptions: true,
|
|
70
|
+
});
|
|
71
|
+
const mcpStartCommand = {
|
|
72
|
+
command,
|
|
73
|
+
describe,
|
|
74
|
+
handler,
|
|
75
|
+
builder,
|
|
76
|
+
};
|
|
77
|
+
exports.default = mcpStartCommand;
|
package/commands/mcp.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const start_1 = __importDefault(require("./mcp/start"));
|
|
7
7
|
const setup_1 = __importDefault(require("./mcp/setup"));
|
|
8
8
|
const yargsUtils_1 = require("../lib/yargsUtils");
|
|
9
|
+
const en_1 = require("../lang/en");
|
|
9
10
|
const command = 'mcp';
|
|
10
11
|
// Leave this as undefined to hide the command
|
|
11
12
|
const describe = undefined;
|
|
@@ -13,7 +14,7 @@ function mcpBuilder(yargs) {
|
|
|
13
14
|
yargs.command(start_1.default).command(setup_1.default).demandCommand(1, '');
|
|
14
15
|
return yargs;
|
|
15
16
|
}
|
|
16
|
-
const builder = (0, yargsUtils_1.makeYargsBuilder)(mcpBuilder, command, describe, {
|
|
17
|
+
const builder = (0, yargsUtils_1.makeYargsBuilder)(mcpBuilder, command, en_1.commands.mcp.describe, {
|
|
17
18
|
useGlobalOptions: true,
|
|
18
19
|
});
|
|
19
20
|
const mcpCommand = {
|
|
@@ -4,6 +4,7 @@ export type ProjectDeployArgs = CommonArgs & ConfigArgs & AccountArgs & Environm
|
|
|
4
4
|
build?: number;
|
|
5
5
|
buildId?: number;
|
|
6
6
|
profile?: string;
|
|
7
|
+
force: boolean;
|
|
7
8
|
};
|
|
8
9
|
declare const projectDeployCommand: YargsCommandModule<unknown, ProjectDeployArgs>;
|
|
9
10
|
export default projectDeployCommand;
|