@hubspot/cli 7.9.0-beta.0 → 7.9.0-beta.2
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/project/__tests__/deploy.test.js +4 -3
- package/lang/en.d.ts +11 -10
- package/lang/en.js +14 -13
- package/lib/__tests__/http.test.d.ts +1 -0
- package/lib/__tests__/http.test.js +40 -0
- package/lib/__tests__/npm.test.js +1 -1
- package/lib/__tests__/sandboxSync.test.js +1 -1
- package/lib/__tests__/usageTracking.test.js +2 -2
- package/lib/configMigrate.js +3 -3
- package/lib/doctor/DiagnosticInfoBuilder.js +1 -1
- package/lib/doctor/Doctor.js +1 -1
- package/lib/doctor/__tests__/DiagnosticInfoBuilder.test.js +4 -2
- package/lib/doctor/__tests__/Doctor.test.js +1 -1
- package/lib/http.d.ts +1 -0
- package/lib/http.js +26 -0
- package/lib/jsonLoader.d.ts +14 -0
- package/lib/jsonLoader.js +60 -0
- package/lib/middleware/__test__/requestMiddleware.test.js +1 -1
- package/lib/middleware/autoUpdateMiddleware.js +1 -1
- package/lib/middleware/commandTargetingUtils.js +1 -0
- package/lib/middleware/fireAlarmMiddleware.js +1 -1
- package/lib/middleware/notificationsMiddleware.js +1 -1
- package/lib/middleware/requestMiddleware.js +1 -1
- package/lib/npm.js +1 -1
- package/lib/projects/__tests__/AppDevModeInterface.test.js +3 -0
- package/lib/projects/create/__tests__/v2.test.js +20 -14
- package/lib/projects/create/v2.js +8 -13
- package/lib/projects/localDev/AppDevModeInterface.d.ts +1 -0
- package/lib/projects/localDev/AppDevModeInterface.js +16 -0
- package/lib/projects/localDev/LocalDevLogger.js +2 -2
- package/lib/projects/localDev/LocalDevManager_DEPRECATED.js +3 -3
- package/lib/projects/localDev/LocalDevWebsocketServer.js +1 -1
- package/lib/prompts/promptUtils.d.ts +8 -0
- package/lib/prompts/promptUtils.js +7 -1
- package/lib/prompts/selectProjectTemplatePrompt.js +4 -0
- package/lib/sandboxSync.js +1 -1
- package/lib/usageTracking.js +2 -2
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +2 -2
- package/mcp-server/tools/cms/HsCreateModuleTool.js +2 -2
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +2 -2
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -9
- package/mcp-server/tools/cms/HsListFunctionsTool.js +1 -1
- package/mcp-server/tools/cms/HsListTool.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateFunctionTool.test.js +7 -4
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +7 -3
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +7 -4
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +5 -1
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +8 -3
- package/mcp-server/tools/cms/__tests__/HsListTool.test.js +8 -3
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +4 -1
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +6 -5
- package/mcp-server/tools/project/CreateProjectTool.js +2 -2
- package/mcp-server/tools/project/DeployProjectTool.d.ts +4 -1
- package/mcp-server/tools/project/DeployProjectTool.js +4 -3
- package/mcp-server/tools/project/DocFetchTool.d.ts +4 -1
- package/mcp-server/tools/project/DocFetchTool.js +7 -6
- package/mcp-server/tools/project/DocsSearchTool.js +5 -5
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.d.ts +4 -1
- package/mcp-server/tools/project/GetApiUsagePatternsByAppIdTool.js +7 -5
- package/mcp-server/tools/project/GetApplicationInfoTool.d.ts +8 -2
- package/mcp-server/tools/project/GetApplicationInfoTool.js +7 -6
- package/mcp-server/tools/project/GetConfigValuesTool.js +4 -4
- package/mcp-server/tools/project/GuidedWalkthroughTool.d.ts +4 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +6 -14
- package/mcp-server/tools/project/UploadProjectTools.d.ts +4 -1
- package/mcp-server/tools/project/UploadProjectTools.js +4 -3
- package/mcp-server/tools/project/ValidateProjectTool.d.ts +4 -1
- package/mcp-server/tools/project/ValidateProjectTool.js +5 -4
- package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +6 -1
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +7 -3
- package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +7 -2
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +8 -3
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +6 -2
- package/mcp-server/tools/project/__tests__/GetApiUsagePatternsByAppIdTool.test.js +8 -3
- package/mcp-server/tools/project/__tests__/GetApplicationInfoTool.test.js +9 -5
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +6 -2
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +43 -13
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +8 -2
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +8 -2
- package/mcp-server/utils/__tests__/content.test.d.ts +1 -0
- package/mcp-server/utils/__tests__/content.test.js +166 -0
- package/mcp-server/utils/__tests__/feedbackTracking.test.d.ts +1 -0
- package/mcp-server/utils/__tests__/feedbackTracking.test.js +121 -0
- package/mcp-server/utils/content.d.ts +1 -1
- package/mcp-server/utils/content.js +8 -1
- package/mcp-server/utils/feedbackTracking.d.ts +1 -0
- package/mcp-server/utils/feedbackTracking.js +41 -0
- package/package.json +2 -2
- package/commands/project/__tests__/fixtures/exampleProject.json +0 -33
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { Separator } from '@inquirer/prompts';
|
|
2
1
|
import { marketplaceDistribution, oAuth, privateDistribution, staticAuth, EMPTY_PROJECT, PROJECT_WITH_APP, FEATURES, } from '../../constants.js';
|
|
3
2
|
import { commands, lib } from '../../../lang/en.js';
|
|
4
3
|
import { listPrompt } from '../../prompts/promptUtils.js';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
4
|
import { isV2Project } from '../platformVersion.js';
|
|
7
5
|
import path from 'path';
|
|
8
6
|
import { getConfigForPlatformVersion } from './legacy.js';
|
|
@@ -75,25 +73,27 @@ export async function calculateComponentTemplateChoices(components, authType, di
|
|
|
75
73
|
if (Array.isArray(supportedAuthTypes) &&
|
|
76
74
|
authType &&
|
|
77
75
|
!supportedAuthTypes.includes(authType.toLowerCase())) {
|
|
78
|
-
|
|
76
|
+
const supportedAuthTypesString = supportedAuthTypes.join(', ');
|
|
77
|
+
disabledReasons.push(commands.project.add.error.authTypeNotAllowed(supportedAuthTypesString));
|
|
79
78
|
}
|
|
80
79
|
if (Array.isArray(supportedDistributions) &&
|
|
81
80
|
distribution &&
|
|
82
81
|
!supportedDistributions.includes(distribution.toLowerCase())) {
|
|
83
|
-
|
|
82
|
+
const supportedDistributionsString = supportedDistributions.join(', ');
|
|
83
|
+
disabledReasons.push(commands.project.add.error.distributionNotAllowed(supportedDistributionsString));
|
|
84
84
|
}
|
|
85
85
|
const templateGate = componentTypeToGateMap[template.cliSelector || template.type];
|
|
86
86
|
if (templateGate) {
|
|
87
87
|
const isUngated = await hasFeature(accountId, templateGate);
|
|
88
88
|
if (!isUngated) {
|
|
89
|
-
disabledReasons.unshift(commands.project.add.error.portalDoesNotHaveAccessToThisFeature(
|
|
89
|
+
disabledReasons.unshift(commands.project.add.error.portalDoesNotHaveAccessToThisFeature());
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
if (disabledReasons.length > 0) {
|
|
93
93
|
disabledComponents.push({
|
|
94
|
-
name:
|
|
94
|
+
name: `${template.label} [${template.cliSelector || template.type}]`,
|
|
95
95
|
value: template,
|
|
96
|
-
disabled: disabledReasons.join(' ')
|
|
96
|
+
disabled: `– ${disabledReasons.join(' ')}`,
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
@@ -104,12 +104,7 @@ export async function calculateComponentTemplateChoices(components, authType, di
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
return disabledComponents.length
|
|
107
|
-
? [
|
|
108
|
-
...enabledComponents,
|
|
109
|
-
new Separator(),
|
|
110
|
-
...disabledComponents,
|
|
111
|
-
new Separator(),
|
|
112
|
-
]
|
|
107
|
+
? [...enabledComponents, ...disabledComponents]
|
|
113
108
|
: [...enabledComponents];
|
|
114
109
|
}
|
|
115
110
|
export async function v2ComponentFlow(platformVersion, projectBase, providedAuth, providedDistribution, accountId) {
|
|
@@ -26,6 +26,7 @@ declare class AppDevModeInterface {
|
|
|
26
26
|
private autoInstallStaticAuthApp;
|
|
27
27
|
private installAppOrOpenInstallUrl;
|
|
28
28
|
private checkTestAccountAppInstallation;
|
|
29
|
+
private validateOauthAppRedirectUrl;
|
|
29
30
|
private resolveAppInstallPromise;
|
|
30
31
|
private handleAppInstallSuccessDevServerMessage;
|
|
31
32
|
private handleAppInstallInitiatedDevServerMessage;
|
|
@@ -13,6 +13,7 @@ import { uiLogger } from '../../ui/logger.js';
|
|
|
13
13
|
import { getOauthAppInstallUrl, getStaticAuthAppInstallUrl, } from '../../app/urls.js';
|
|
14
14
|
import { isDeveloperTestAccount, isSandbox } from '../../accountTypes.js';
|
|
15
15
|
import SpinniesManager from '../../ui/SpinniesManager.js';
|
|
16
|
+
import { isServerRunningAtUrl } from '../../http.js';
|
|
16
17
|
class AppDevModeInterface {
|
|
17
18
|
localDevState;
|
|
18
19
|
localDevLogger;
|
|
@@ -214,6 +215,18 @@ class AppDevModeInterface {
|
|
|
214
215
|
}
|
|
215
216
|
return { needsInstall: !isInstalledWithScopeGroups, isReinstall };
|
|
216
217
|
}
|
|
218
|
+
async validateOauthAppRedirectUrl() {
|
|
219
|
+
const redirectUrl = this.appNode?.config.auth.redirectUrls[0];
|
|
220
|
+
if (!redirectUrl) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const serverIsRunningAtRedirectUrl = await isServerRunningAtUrl(redirectUrl);
|
|
224
|
+
if (!serverIsRunningAtRedirectUrl) {
|
|
225
|
+
uiLogger.log('');
|
|
226
|
+
uiLogger.error(lib.AppDevModeInterface.oauthAppRedirectUrlError(redirectUrl));
|
|
227
|
+
process.exit(EXIT_CODES.ERROR);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
217
230
|
resolveAppInstallPromise() {
|
|
218
231
|
if (this.appInstallResolve) {
|
|
219
232
|
this.appInstallResolve();
|
|
@@ -284,6 +297,9 @@ class AppDevModeInterface {
|
|
|
284
297
|
failColor: 'white',
|
|
285
298
|
});
|
|
286
299
|
}
|
|
300
|
+
if (this.isOAuthApp()) {
|
|
301
|
+
await this.validateOauthAppRedirectUrl();
|
|
302
|
+
}
|
|
287
303
|
this.localDevState.addListener('devServerMessage', this.onDevServerMessage);
|
|
288
304
|
await this.installAppOrOpenInstallUrl(isReinstall || false);
|
|
289
305
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getAccountId, hasLocalStateFlag } from '@hubspot/local-dev-lib/config';
|
|
2
2
|
import { getConfigDefaultAccount } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { uiLogger } from '../../ui/logger.js';
|
|
4
|
-
import {
|
|
4
|
+
import { uiLine, uiAccountDescription, uiCommandReference, } from '../../ui/index.js';
|
|
5
5
|
import { lib } from '../../../lang/en.js';
|
|
6
6
|
import SpinniesManager from '../../ui/SpinniesManager.js';
|
|
7
7
|
import { logError } from '../../errorHandlers/index.js';
|
|
@@ -75,7 +75,7 @@ class LocalDevLogger {
|
|
|
75
75
|
if (!this.state.debug) {
|
|
76
76
|
console.clear();
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
uiLogger.log(lib.LocalDevManager.headerMessage);
|
|
79
79
|
uiLogger.log(lib.LocalDevManager.learnMoreLocalDevServer);
|
|
80
80
|
uiLogger.log('');
|
|
81
81
|
uiLogger.log(lib.LocalDevManager.running(this.state.projectConfig.name, uiAccountDescription(this.state.targetProjectAccountId)));
|
|
@@ -11,7 +11,7 @@ import { EXIT_CODES } from '../../enums/exitCodes.js';
|
|
|
11
11
|
import { getAccountHomeUrl } from '../urls.js';
|
|
12
12
|
import { componentIsApp, componentIsPublicApp, CONFIG_FILES, getAppCardConfigs, getComponentUid, } from '../structure.js';
|
|
13
13
|
import { ComponentTypes, } from '../../../types/Projects.js';
|
|
14
|
-
import { UI_COLORS, uiCommandReference, uiAccountDescription,
|
|
14
|
+
import { UI_COLORS, uiCommandReference, uiAccountDescription, uiLink, uiLine, } from '../../ui/index.js';
|
|
15
15
|
import { logError } from '../../errorHandlers/index.js';
|
|
16
16
|
import { installAppBrowserPrompt } from '../../prompts/installAppPrompt.js';
|
|
17
17
|
import { confirmPrompt } from '../../prompts/promptUtils.js';
|
|
@@ -131,8 +131,8 @@ class LocalDevManager {
|
|
|
131
131
|
else if (!this.debug) {
|
|
132
132
|
console.clear();
|
|
133
133
|
}
|
|
134
|
-
|
|
135
|
-
uiLogger.log(uiLink(lib.LocalDevManager.learnMoreLocalDevServer, 'https://developers.hubspot.com/docs/
|
|
134
|
+
uiLogger.log(lib.LocalDevManager.headerMessage);
|
|
135
|
+
uiLogger.log(uiLink(lib.LocalDevManager.learnMoreLocalDevServer, 'https://developers.hubspot.com/docs/developer-tooling/local-development/hubspot-cli/project-commands'));
|
|
136
136
|
uiLogger.log('');
|
|
137
137
|
uiLogger.log(chalk.hex(UI_COLORS.SORBET)(lib.LocalDevManager.running(this.projectConfig.name, uiAccountDescription(this.targetAccountId))));
|
|
138
138
|
uiLogger.log(lib.LocalDevManager.viewProjectLink(this.projectConfig.name, this.targetProjectAccountId));
|
|
@@ -6,7 +6,7 @@ import { LOCAL_DEV_UI_MESSAGE_SEND_TYPES, LOCAL_DEV_SERVER_MESSAGE_TYPES, CONFIG
|
|
|
6
6
|
import { lib } from '../../../lang/en.js';
|
|
7
7
|
import { removeAnsiCodes } from '../../ui/removeAnsiCodes.js';
|
|
8
8
|
import { isDeployWebsocketMessage, isViewedWelcomeScreenWebsocketMessage, isUploadWebsocketMessage, isAppInstallFailureWebsocketMessage, isAppInstallSuccessWebsocketMessage, isAppInstallInitiatedWebsocketMessage, } from './localDevWebsocketServerUtils.js';
|
|
9
|
-
import pkg from '
|
|
9
|
+
import { pkg } from '../../jsonLoader.js';
|
|
10
10
|
const LOCAL_DEV_WEBSOCKET_SERVER_VERSION = 2;
|
|
11
11
|
const LOG_PREFIX = '[LocalDevWebsocketServer]';
|
|
12
12
|
const DOMAINS = ['hubspot.com', 'hubspotqa.com'];
|
|
@@ -6,6 +6,14 @@ export declare const PROMPT_THEME: {
|
|
|
6
6
|
idle: string;
|
|
7
7
|
};
|
|
8
8
|
};
|
|
9
|
+
export declare const CHECKBOX_PROMPT_THEME: {
|
|
10
|
+
prefix: {
|
|
11
|
+
idle: string;
|
|
12
|
+
};
|
|
13
|
+
style: {
|
|
14
|
+
disabledChoice: (text: string) => string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
9
17
|
export declare function promptUser<T extends GenericPromptResponse>(config: PromptConfig<T> | PromptConfig<T>[]): Promise<T>;
|
|
10
18
|
export declare function confirmPrompt(message: string, options?: {
|
|
11
19
|
defaultAnswer?: boolean;
|
|
@@ -5,6 +5,12 @@ import { lib } from '../../lang/en.js';
|
|
|
5
5
|
import { uiLogger } from '../ui/logger.js';
|
|
6
6
|
export const Separator = new _Separator();
|
|
7
7
|
export const PROMPT_THEME = { prefix: { idle: chalk.green('?') } };
|
|
8
|
+
export const CHECKBOX_PROMPT_THEME = {
|
|
9
|
+
prefix: { idle: chalk.green('?') },
|
|
10
|
+
style: {
|
|
11
|
+
disabledChoice: (text) => chalk.dim(` ◯ ${text}`),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
8
14
|
function isUserCancellationError(error) {
|
|
9
15
|
return error instanceof Error && error.name === 'ExitPromptError';
|
|
10
16
|
}
|
|
@@ -147,7 +153,7 @@ function handleCheckboxPrompt(config) {
|
|
|
147
153
|
pageSize: config.pageSize,
|
|
148
154
|
validate: config.validate,
|
|
149
155
|
loop: config.loop,
|
|
150
|
-
theme:
|
|
156
|
+
theme: CHECKBOX_PROMPT_THEME,
|
|
151
157
|
shortcuts: {
|
|
152
158
|
invert: null,
|
|
153
159
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Separator } from '@inquirer/prompts';
|
|
2
2
|
import { promptUser } from './promptUtils.js';
|
|
3
3
|
import { lib } from '../../lang/en.js';
|
|
4
|
+
import { uiLogger } from '../ui/logger.js';
|
|
4
5
|
function findTemplateByNameOrLabel(projectTemplates, templateNameOrLabel) {
|
|
5
6
|
return projectTemplates.find(t => t.name === templateNameOrLabel || t.label === templateNameOrLabel);
|
|
6
7
|
}
|
|
@@ -55,6 +56,9 @@ export async function selectProjectTemplatePrompt(promptOptions, projectTemplate
|
|
|
55
56
|
pageSize: componentTemplates?.length,
|
|
56
57
|
},
|
|
57
58
|
]);
|
|
59
|
+
if (result.componentTemplates?.length === 0) {
|
|
60
|
+
uiLogger.log(lib.projects.add.nothingAdded);
|
|
61
|
+
}
|
|
58
62
|
if (!result.componentTemplates) {
|
|
59
63
|
result.componentTemplates = selectedComponents;
|
|
60
64
|
}
|
package/lib/sandboxSync.js
CHANGED
|
@@ -85,7 +85,7 @@ export async function syncSandbox(accountConfig, parentAccountConfig, env, syncT
|
|
|
85
85
|
else if (isSpecifiedError(err, {
|
|
86
86
|
statusCode: 404,
|
|
87
87
|
})) {
|
|
88
|
-
uiCommandDisabledBanner('hs sandbox sync', 'https://
|
|
88
|
+
uiCommandDisabledBanner('hs sandbox sync', 'https://developers.hubspot.com/docs/developer-tooling/local-development/hubspot-cli/project-commands');
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
91
|
logError(err, new ApiErrorContext({
|
package/lib/usageTracking.js
CHANGED
|
@@ -2,9 +2,9 @@ import { trackUsage } from '@hubspot/local-dev-lib/trackUsage';
|
|
|
2
2
|
import { isTrackingAllowed, getAccountConfig, } from '@hubspot/local-dev-lib/config';
|
|
3
3
|
import { API_KEY_AUTH_METHOD } from '@hubspot/local-dev-lib/constants/auth';
|
|
4
4
|
import { uiLogger } from './ui/logger.js';
|
|
5
|
-
import
|
|
6
|
-
const version = packageJson.version;
|
|
5
|
+
import { pkg } from './jsonLoader.js';
|
|
7
6
|
import { debugError } from './errorHandlers/index.js';
|
|
7
|
+
const version = pkg.version;
|
|
8
8
|
export const EventClass = {
|
|
9
9
|
USAGE: 'USAGE',
|
|
10
10
|
INTERACTION: 'INTERACTION',
|
|
@@ -80,10 +80,10 @@ export class HsCreateFunctionTool extends Tool {
|
|
|
80
80
|
}
|
|
81
81
|
try {
|
|
82
82
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
83
|
-
return formatTextContents(stdout, stderr);
|
|
83
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
84
84
|
}
|
|
85
85
|
catch (error) {
|
|
86
|
-
return formatTextContents(error instanceof Error ? error.message : `${error}`);
|
|
86
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, error instanceof Error ? error.message : `${error}`);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
register() {
|
|
@@ -102,10 +102,10 @@ export class HsCreateModuleTool extends Tool {
|
|
|
102
102
|
}
|
|
103
103
|
try {
|
|
104
104
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
105
|
-
return formatTextContents(stdout, stderr);
|
|
105
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
106
106
|
}
|
|
107
107
|
catch (error) {
|
|
108
|
-
return formatTextContents(error instanceof Error ? error.message : `${error}`);
|
|
108
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, error instanceof Error ? error.message : `${error}`);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
register() {
|
|
@@ -59,10 +59,10 @@ export class HsCreateTemplateTool extends Tool {
|
|
|
59
59
|
}
|
|
60
60
|
try {
|
|
61
61
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
62
|
-
return formatTextContents(stdout, stderr);
|
|
62
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
63
63
|
}
|
|
64
64
|
catch (error) {
|
|
65
|
-
return formatTextContents(error instanceof Error ? error.message : `${error}`);
|
|
65
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, error instanceof Error ? error.message : `${error}`);
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
register() {
|
|
@@ -52,18 +52,11 @@ export class HsFunctionLogsTool extends Tool {
|
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
54
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
55
|
-
return formatTextContents(stdout, stderr);
|
|
55
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
56
56
|
}
|
|
57
57
|
catch (error) {
|
|
58
58
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
59
|
-
return {
|
|
60
|
-
content: [
|
|
61
|
-
{
|
|
62
|
-
type: 'text',
|
|
63
|
-
text: `Error executing hs logs command: ${errorMessage}`,
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
};
|
|
59
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, `Error executing hs logs command: ${errorMessage}`);
|
|
67
60
|
}
|
|
68
61
|
}
|
|
69
62
|
register() {
|
|
@@ -34,7 +34,7 @@ export class HsListFunctionsTool extends Tool {
|
|
|
34
34
|
}
|
|
35
35
|
try {
|
|
36
36
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
37
|
-
return formatTextContents(stdout, stderr);
|
|
37
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
38
38
|
}
|
|
39
39
|
catch (error) {
|
|
40
40
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -34,7 +34,7 @@ export class HsListTool extends Tool {
|
|
|
34
34
|
}
|
|
35
35
|
try {
|
|
36
36
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
37
|
-
return formatTextContents(stdout, stderr);
|
|
37
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
38
38
|
}
|
|
39
39
|
catch (error) {
|
|
40
40
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -2,13 +2,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
2
2
|
import { HsCreateFunctionTool } from '../HsCreateFunctionTool.js';
|
|
3
3
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
4
4
|
import { addFlag } from '../../../utils/command.js';
|
|
5
|
-
import {
|
|
5
|
+
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
6
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
7
7
|
vi.mock('../../../utils/project');
|
|
8
8
|
vi.mock('../../../utils/command');
|
|
9
9
|
vi.mock('../../../utils/toolUsageTracking', () => ({
|
|
10
10
|
trackToolUsage: vi.fn(),
|
|
11
11
|
}));
|
|
12
|
+
vi.mock('../../../utils/feedbackTracking');
|
|
13
|
+
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
12
14
|
const mockRunCommandInDir = runCommandInDir;
|
|
13
15
|
const mockAddFlag = addFlag;
|
|
14
16
|
describe('HsCreateFunctionTool', () => {
|
|
@@ -23,16 +25,17 @@ describe('HsCreateFunctionTool', () => {
|
|
|
23
25
|
};
|
|
24
26
|
mockRegisteredTool = {};
|
|
25
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
28
|
+
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
26
29
|
tool = new HsCreateFunctionTool(mockMcpServer);
|
|
27
30
|
});
|
|
28
31
|
describe('register', () => {
|
|
29
32
|
it('should register the tool with the MCP server', () => {
|
|
30
33
|
const result = tool.register();
|
|
31
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-function', {
|
|
34
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-function', expect.objectContaining({
|
|
32
35
|
title: 'Create HubSpot CMS Serverless Function',
|
|
33
|
-
description:
|
|
36
|
+
description: expect.stringContaining('Creates a new HubSpot CMS serverless function'),
|
|
34
37
|
inputSchema: expect.any(Object),
|
|
35
|
-
}, expect.any(Function));
|
|
38
|
+
}), expect.any(Function));
|
|
36
39
|
expect(result).toBe(mockRegisteredTool);
|
|
37
40
|
});
|
|
38
41
|
});
|
|
@@ -2,12 +2,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
2
2
|
import { HsCreateModuleTool } from '../HsCreateModuleTool.js';
|
|
3
3
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
4
4
|
import { addFlag } from '../../../utils/command.js';
|
|
5
|
+
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
5
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
7
|
vi.mock('../../../utils/project');
|
|
7
8
|
vi.mock('../../../utils/command');
|
|
8
9
|
vi.mock('../../../utils/toolUsageTracking', () => ({
|
|
9
10
|
trackToolUsage: vi.fn(),
|
|
10
11
|
}));
|
|
12
|
+
vi.mock('../../../utils/feedbackTracking');
|
|
13
|
+
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
11
14
|
const mockRunCommandInDir = runCommandInDir;
|
|
12
15
|
const mockAddFlag = addFlag;
|
|
13
16
|
describe('HsCreateModuleTool', () => {
|
|
@@ -22,16 +25,17 @@ describe('HsCreateModuleTool', () => {
|
|
|
22
25
|
};
|
|
23
26
|
mockRegisteredTool = {};
|
|
24
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
28
|
+
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
25
29
|
tool = new HsCreateModuleTool(mockMcpServer);
|
|
26
30
|
});
|
|
27
31
|
describe('register', () => {
|
|
28
32
|
it('should register the tool with the MCP server', () => {
|
|
29
33
|
const result = tool.register();
|
|
30
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-module', {
|
|
34
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-module', expect.objectContaining({
|
|
31
35
|
title: 'Create HubSpot CMS Module',
|
|
32
|
-
description: 'Creates a new HubSpot CMS module
|
|
36
|
+
description: expect.stringContaining('Creates a new HubSpot CMS module'),
|
|
33
37
|
inputSchema: expect.any(Object),
|
|
34
|
-
}, expect.any(Function));
|
|
38
|
+
}), expect.any(Function));
|
|
35
39
|
expect(result).toBe(mockRegisteredTool);
|
|
36
40
|
});
|
|
37
41
|
});
|
|
@@ -2,13 +2,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
2
2
|
import { HsCreateTemplateTool } from '../HsCreateTemplateTool.js';
|
|
3
3
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
4
4
|
import { addFlag } from '../../../utils/command.js';
|
|
5
|
-
import {
|
|
5
|
+
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
6
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
7
7
|
vi.mock('../../../utils/project');
|
|
8
8
|
vi.mock('../../../utils/command');
|
|
9
9
|
vi.mock('../../../utils/toolUsageTracking', () => ({
|
|
10
10
|
trackToolUsage: vi.fn(),
|
|
11
11
|
}));
|
|
12
|
+
vi.mock('../../../utils/feedbackTracking');
|
|
13
|
+
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
12
14
|
const mockRunCommandInDir = runCommandInDir;
|
|
13
15
|
const mockAddFlag = addFlag;
|
|
14
16
|
describe('HsCreateTemplateTool', () => {
|
|
@@ -23,16 +25,17 @@ describe('HsCreateTemplateTool', () => {
|
|
|
23
25
|
};
|
|
24
26
|
mockRegisteredTool = {};
|
|
25
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
28
|
+
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
26
29
|
tool = new HsCreateTemplateTool(mockMcpServer);
|
|
27
30
|
});
|
|
28
31
|
describe('register', () => {
|
|
29
32
|
it('should register the tool with the MCP server', () => {
|
|
30
33
|
const result = tool.register();
|
|
31
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-template', {
|
|
34
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-template', expect.objectContaining({
|
|
32
35
|
title: 'Create HubSpot CMS Template',
|
|
33
|
-
description:
|
|
36
|
+
description: expect.stringContaining('Creates a new HubSpot CMS template'),
|
|
34
37
|
inputSchema: expect.any(Object),
|
|
35
|
-
}, expect.any(Function));
|
|
38
|
+
}), expect.any(Function));
|
|
36
39
|
expect(result).toBe(mockRegisteredTool);
|
|
37
40
|
});
|
|
38
41
|
});
|
|
@@ -2,12 +2,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
2
2
|
import { HsFunctionLogsTool } from '../HsFunctionLogsTool.js';
|
|
3
3
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
4
4
|
import { addFlag } from '../../../utils/command.js';
|
|
5
|
+
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
5
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
7
|
vi.mock('../../../utils/project');
|
|
7
8
|
vi.mock('../../../utils/command');
|
|
8
9
|
vi.mock('../../../utils/toolUsageTracking', () => ({
|
|
9
10
|
trackToolUsage: vi.fn(),
|
|
10
11
|
}));
|
|
12
|
+
vi.mock('../../../utils/feedbackTracking');
|
|
13
|
+
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
11
14
|
const mockRunCommandInDir = runCommandInDir;
|
|
12
15
|
const mockAddFlag = addFlag;
|
|
13
16
|
describe('HsFunctionLogsTool', () => {
|
|
@@ -22,6 +25,7 @@ describe('HsFunctionLogsTool', () => {
|
|
|
22
25
|
};
|
|
23
26
|
mockRegisteredTool = {};
|
|
24
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
28
|
+
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
25
29
|
tool = new HsFunctionLogsTool(mockMcpServer);
|
|
26
30
|
});
|
|
27
31
|
describe('register', () => {
|
|
@@ -29,7 +33,7 @@ describe('HsFunctionLogsTool', () => {
|
|
|
29
33
|
const result = tool.register();
|
|
30
34
|
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-cms-serverless-function-logs', expect.objectContaining({
|
|
31
35
|
title: 'Get HubSpot CMS serverless function logs for an endpoint',
|
|
32
|
-
description: 'Retrieve logs for HubSpot CMS serverless functions
|
|
36
|
+
description: expect.stringContaining('Retrieve logs for HubSpot CMS serverless functions'),
|
|
33
37
|
inputSchema: expect.any(Object),
|
|
34
38
|
}), expect.any(Function));
|
|
35
39
|
expect(result).toBe(mockRegisteredTool);
|
|
@@ -2,12 +2,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
2
2
|
import { HsListFunctionsTool } from '../HsListFunctionsTool.js';
|
|
3
3
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
4
4
|
import { addFlag } from '../../../utils/command.js';
|
|
5
|
+
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
5
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
7
|
vi.mock('../../../utils/project');
|
|
7
8
|
vi.mock('../../../utils/command');
|
|
8
9
|
vi.mock('../../../utils/toolUsageTracking', () => ({
|
|
9
10
|
trackToolUsage: vi.fn(),
|
|
10
11
|
}));
|
|
12
|
+
vi.mock('../../../utils/feedbackTracking');
|
|
13
|
+
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
11
14
|
const mockRunCommandInDir = runCommandInDir;
|
|
12
15
|
const mockAddFlag = addFlag;
|
|
13
16
|
describe('HsListFunctionsTool', () => {
|
|
@@ -22,16 +25,18 @@ describe('HsListFunctionsTool', () => {
|
|
|
22
25
|
};
|
|
23
26
|
mockRegisteredTool = {};
|
|
24
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
28
|
+
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
25
29
|
tool = new HsListFunctionsTool(mockMcpServer);
|
|
26
30
|
});
|
|
27
31
|
describe('register', () => {
|
|
28
32
|
it('should register the tool with the MCP server', () => {
|
|
29
33
|
const result = tool.register();
|
|
30
|
-
|
|
34
|
+
// First assertion - verify original description
|
|
35
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-cms-serverless-functions', expect.objectContaining({
|
|
31
36
|
title: 'List HubSpot CMS Serverless Functions',
|
|
32
|
-
description: 'Get a list of all serverless functions deployed in a HubSpot portal/account
|
|
37
|
+
description: expect.stringContaining('Get a list of all serverless functions deployed in a HubSpot portal/account'),
|
|
33
38
|
inputSchema: expect.any(Object),
|
|
34
|
-
}, expect.any(Function));
|
|
39
|
+
}), expect.any(Function));
|
|
35
40
|
expect(result).toBe(mockRegisteredTool);
|
|
36
41
|
});
|
|
37
42
|
});
|
|
@@ -2,12 +2,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
2
2
|
import { HsListTool } from '../HsListTool.js';
|
|
3
3
|
import { runCommandInDir } from '../../../utils/project.js';
|
|
4
4
|
import { addFlag } from '../../../utils/command.js';
|
|
5
|
+
import { mcpFeedbackRequest } from '../../../utils/feedbackTracking.js';
|
|
5
6
|
vi.mock('@modelcontextprotocol/sdk/server/mcp.js');
|
|
6
7
|
vi.mock('../../../utils/project');
|
|
7
8
|
vi.mock('../../../utils/command');
|
|
8
9
|
vi.mock('../../../utils/toolUsageTracking', () => ({
|
|
9
10
|
trackToolUsage: vi.fn(),
|
|
10
11
|
}));
|
|
12
|
+
vi.mock('../../../utils/feedbackTracking');
|
|
13
|
+
const mockMcpFeedbackRequest = mcpFeedbackRequest;
|
|
11
14
|
const mockRunCommandInDir = runCommandInDir;
|
|
12
15
|
const mockAddFlag = addFlag;
|
|
13
16
|
describe('HsListTool', () => {
|
|
@@ -22,16 +25,18 @@ describe('HsListTool', () => {
|
|
|
22
25
|
};
|
|
23
26
|
mockRegisteredTool = {};
|
|
24
27
|
mockMcpServer.registerTool.mockReturnValue(mockRegisteredTool);
|
|
28
|
+
mockMcpFeedbackRequest.mockResolvedValue('');
|
|
25
29
|
tool = new HsListTool(mockMcpServer);
|
|
26
30
|
});
|
|
27
31
|
describe('register', () => {
|
|
28
32
|
it('should register the tool with the MCP server', () => {
|
|
29
33
|
const result = tool.register();
|
|
30
|
-
|
|
34
|
+
// First assertion - verify original description
|
|
35
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-cms-remote-contents', expect.objectContaining({
|
|
31
36
|
title: 'List HubSpot CMS Directory Contents',
|
|
32
|
-
description: 'List remote contents of a HubSpot CMS directory
|
|
37
|
+
description: expect.stringContaining('List remote contents of a HubSpot CMS directory'),
|
|
33
38
|
inputSchema: expect.any(Object),
|
|
34
|
-
}, expect.any(Function));
|
|
39
|
+
}), expect.any(Function));
|
|
35
40
|
expect(result).toBe(mockRegisteredTool);
|
|
36
41
|
});
|
|
37
42
|
});
|
|
@@ -3,18 +3,21 @@ import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
declare const inputSchemaZodObject: z.ZodObject<{
|
|
5
5
|
absoluteProjectPath: z.ZodString;
|
|
6
|
+
absoluteCurrentWorkingDirectory: z.ZodString;
|
|
6
7
|
addApp: z.ZodBoolean;
|
|
7
8
|
distribution: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"marketplace">, z.ZodLiteral<"private">]>>;
|
|
8
9
|
auth: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"static">, z.ZodLiteral<"oauth">]>>;
|
|
9
10
|
features: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"card">, z.ZodLiteral<"settings">, z.ZodLiteral<"app-function">, z.ZodLiteral<"webhooks">, z.ZodLiteral<"workflow-action">, z.ZodLiteral<"workflow-action-tool">, z.ZodLiteral<"app-object">, z.ZodLiteral<"app-event">, z.ZodLiteral<"scim">, z.ZodLiteral<"page">]>, "many">>;
|
|
10
11
|
}, "strip", z.ZodTypeAny, {
|
|
11
12
|
absoluteProjectPath: string;
|
|
13
|
+
absoluteCurrentWorkingDirectory: string;
|
|
12
14
|
addApp: boolean;
|
|
13
15
|
auth?: "oauth" | "static" | undefined;
|
|
14
16
|
distribution?: "marketplace" | "private" | undefined;
|
|
15
17
|
features?: ("card" | "settings" | "page" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
16
18
|
}, {
|
|
17
19
|
absoluteProjectPath: string;
|
|
20
|
+
absoluteCurrentWorkingDirectory: string;
|
|
18
21
|
addApp: boolean;
|
|
19
22
|
auth?: "oauth" | "static" | undefined;
|
|
20
23
|
distribution?: "marketplace" | "private" | undefined;
|
|
@@ -23,7 +26,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
23
26
|
export type AddFeatureInputSchema = z.infer<typeof inputSchemaZodObject>;
|
|
24
27
|
export declare class AddFeatureToProjectTool extends Tool<AddFeatureInputSchema> {
|
|
25
28
|
constructor(mcpServer: McpServer);
|
|
26
|
-
handler({ absoluteProjectPath, distribution, auth, features, addApp, }: AddFeatureInputSchema): Promise<TextContentResponse>;
|
|
29
|
+
handler({ absoluteProjectPath, absoluteCurrentWorkingDirectory, distribution, auth, features, addApp, }: AddFeatureInputSchema): Promise<TextContentResponse>;
|
|
27
30
|
register(): RegisteredTool;
|
|
28
31
|
}
|
|
29
32
|
export {};
|
|
@@ -2,12 +2,13 @@ import { Tool } from '../../types.js';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { APP_AUTH_TYPES, APP_DISTRIBUTION_TYPES, } from '../../../lib/constants.js';
|
|
4
4
|
import { addFlag } from '../../utils/command.js';
|
|
5
|
-
import { absoluteProjectPath, features } from './constants.js';
|
|
5
|
+
import { absoluteCurrentWorkingDirectory, absoluteProjectPath, features, } from './constants.js';
|
|
6
6
|
import { runCommandInDir } from '../../utils/project.js';
|
|
7
7
|
import { formatTextContents, formatTextContent } from '../../utils/content.js';
|
|
8
8
|
import { trackToolUsage } from '../../utils/toolUsageTracking.js';
|
|
9
9
|
const inputSchema = {
|
|
10
10
|
absoluteProjectPath,
|
|
11
|
+
absoluteCurrentWorkingDirectory,
|
|
11
12
|
addApp: z
|
|
12
13
|
.boolean()
|
|
13
14
|
.describe('Should an app be added? If there is no app in the project, an app must be added to add a feature'),
|
|
@@ -34,7 +35,7 @@ export class AddFeatureToProjectTool extends Tool {
|
|
|
34
35
|
constructor(mcpServer) {
|
|
35
36
|
super(mcpServer);
|
|
36
37
|
}
|
|
37
|
-
async handler({ absoluteProjectPath, distribution, auth, features, addApp, }) {
|
|
38
|
+
async handler({ absoluteProjectPath, absoluteCurrentWorkingDirectory, distribution, auth, features, addApp, }) {
|
|
38
39
|
try {
|
|
39
40
|
await trackToolUsage(toolName);
|
|
40
41
|
let command = `hs project add`;
|
|
@@ -59,16 +60,16 @@ export class AddFeatureToProjectTool extends Tool {
|
|
|
59
60
|
// If features isn't provided, pass an empty array to bypass the prompt
|
|
60
61
|
command = addFlag(command, 'features', features || []);
|
|
61
62
|
const { stdout, stderr } = await runCommandInDir(absoluteProjectPath, command);
|
|
62
|
-
return formatTextContents(stdout, stderr);
|
|
63
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
63
64
|
}
|
|
64
65
|
catch (error) {
|
|
65
|
-
return formatTextContents(error instanceof Error ? error.message : `${error}`);
|
|
66
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, error instanceof Error ? error.message : `${error}`);
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
register() {
|
|
69
70
|
return this.mcpServer.registerTool(toolName, {
|
|
70
71
|
title: 'Add feature to HubSpot Project',
|
|
71
|
-
description: `Adds a feature to an existing HubSpot project.
|
|
72
|
+
description: `Adds a feature to an existing HubSpot project.
|
|
72
73
|
Only works for projects with platformVersion '2025.2' and beyond`,
|
|
73
74
|
inputSchema,
|
|
74
75
|
}, this.handler);
|
|
@@ -77,10 +77,10 @@ export class CreateProjectTool extends Tool {
|
|
|
77
77
|
command = addFlag(command, 'features', features || []);
|
|
78
78
|
try {
|
|
79
79
|
const { stdout, stderr } = await runCommandInDir(absoluteCurrentWorkingDirectory, command);
|
|
80
|
-
return formatTextContents(stdout, stderr);
|
|
80
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, stdout, stderr);
|
|
81
81
|
}
|
|
82
82
|
catch (error) {
|
|
83
|
-
return formatTextContents(error instanceof Error ? error.message : `${error}`);
|
|
83
|
+
return formatTextContents(absoluteCurrentWorkingDirectory, error instanceof Error ? error.message : `${error}`);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
register() {
|