@hubspot/cli 7.7.33-experimental.0 → 7.7.34-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/__tests__/install.test.d.ts +1 -0
- package/commands/app/__tests__/install.test.js +47 -0
- package/commands/app/install.d.ts +8 -0
- package/commands/app/install.js +122 -0
- package/commands/app.js +6 -1
- package/commands/getStarted.js +2 -16
- package/commands/project/dev/unifiedFlow.js +1 -1
- package/commands/project/upload.d.ts +2 -2
- package/commands/project/upload.js +1 -1
- package/commands/testAccount/create.js +3 -0
- package/lang/en.d.ts +23 -1
- package/lang/en.js +23 -1
- package/lib/mcp/setup.js +1 -1
- package/lib/projectProfiles.d.ts +1 -1
- package/lib/projectProfiles.js +10 -2
- package/lib/projects/localDev/helpers/project.d.ts +2 -2
- package/lib/projects/localDev/helpers/project.js +5 -6
- package/lib/projects/structure.d.ts +2 -2
- package/lib/projects/upload.d.ts +2 -1
- package/lib/projects/upload.js +1 -0
- package/mcp-server/tools/cms/HsCreateFunctionTool.js +1 -1
- package/mcp-server/tools/cms/HsCreateModuleTool.js +1 -1
- package/mcp-server/tools/cms/HsCreateTemplateTool.js +1 -1
- package/mcp-server/tools/cms/HsFunctionLogsTool.js +2 -2
- 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 +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateModuleTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsCreateTemplateTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsFunctionLogsTool.test.js +2 -2
- package/mcp-server/tools/cms/__tests__/HsListFunctionsTool.test.js +1 -1
- package/mcp-server/tools/cms/__tests__/HsListTool.test.js +1 -1
- package/mcp-server/tools/project/AddFeatureToProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/AddFeatureToProjectTool.js +3 -3
- package/mcp-server/tools/project/CreateProjectTool.d.ts +3 -3
- package/mcp-server/tools/project/CreateProjectTool.js +5 -5
- package/mcp-server/tools/project/DeployProjectTool.js +1 -1
- package/mcp-server/tools/project/DocFetchTool.js +2 -2
- package/mcp-server/tools/project/DocsSearchTool.js +2 -2
- package/mcp-server/tools/project/GetConfigValuesTool.js +1 -1
- package/mcp-server/tools/project/GuidedWalkthroughTool.js +1 -1
- package/mcp-server/tools/project/UploadProjectTools.js +2 -2
- package/mcp-server/tools/project/ValidateProjectTool.js +1 -1
- package/mcp-server/tools/project/__tests__/AddFeatureToProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/CreateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DeployProjectTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/DocFetchTool.test.js +2 -2
- package/mcp-server/tools/project/__tests__/DocsSearchTool.test.js +2 -2
- package/mcp-server/tools/project/__tests__/GetConfigValuesTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/GuidedWalkthroughTool.test.js +1 -1
- package/mcp-server/tools/project/__tests__/UploadProjectTools.test.js +1 -1
- package/mcp-server/tools/project/__tests__/ValidateProjectTool.test.js +1 -1
- package/mcp-server/tools/project/constants.d.ts +1 -1
- package/mcp-server/tools/project/constants.js +9 -3
- package/package.json +1 -1
- package/types/Yargs.d.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import yargs from 'yargs';
|
|
2
|
+
import { addAccountOptions, addConfigOptions, addUseEnvironmentOptions, addGlobalOptions, addJSONOutputOptions, } from '../../../lib/commonOpts.js';
|
|
3
|
+
import installCommand from '../install.js';
|
|
4
|
+
vi.mock('../../../lib/commonOpts');
|
|
5
|
+
describe('commands/app/install', () => {
|
|
6
|
+
const yargsMock = yargs;
|
|
7
|
+
describe('command', () => {
|
|
8
|
+
it('should have the correct command structure', () => {
|
|
9
|
+
expect(installCommand.command).toEqual('install <test-account-id>');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
describe('describe', () => {
|
|
13
|
+
it('should provide a description', () => {
|
|
14
|
+
expect(installCommand.describe).not.toBeDefined();
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
describe('builder', () => {
|
|
18
|
+
it('should support the correct options', () => {
|
|
19
|
+
installCommand.builder(yargsMock);
|
|
20
|
+
expect(addGlobalOptions).toHaveBeenCalledTimes(1);
|
|
21
|
+
expect(addGlobalOptions).toHaveBeenCalledWith(yargsMock);
|
|
22
|
+
expect(addAccountOptions).toHaveBeenCalledTimes(1);
|
|
23
|
+
expect(addAccountOptions).toHaveBeenCalledWith(yargsMock);
|
|
24
|
+
expect(addConfigOptions).toHaveBeenCalledTimes(1);
|
|
25
|
+
expect(addConfigOptions).toHaveBeenCalledWith(yargsMock);
|
|
26
|
+
expect(addUseEnvironmentOptions).toHaveBeenCalledTimes(1);
|
|
27
|
+
expect(addUseEnvironmentOptions).toHaveBeenCalledWith(yargsMock);
|
|
28
|
+
expect(addJSONOutputOptions).toHaveBeenCalledTimes(1);
|
|
29
|
+
expect(addJSONOutputOptions).toHaveBeenCalledWith(yargsMock);
|
|
30
|
+
expect(yargsMock.positional).toHaveBeenCalledTimes(1);
|
|
31
|
+
expect(yargsMock.positional).toHaveBeenCalledWith('test-account-id', expect.objectContaining({
|
|
32
|
+
type: 'number',
|
|
33
|
+
required: true,
|
|
34
|
+
describe: expect.any(String),
|
|
35
|
+
}));
|
|
36
|
+
expect(yargsMock.option).toHaveBeenCalledTimes(2);
|
|
37
|
+
expect(yargsMock.option).toHaveBeenCalledWith('app-uid', expect.objectContaining({
|
|
38
|
+
type: 'string',
|
|
39
|
+
describe: expect.any(String),
|
|
40
|
+
}));
|
|
41
|
+
expect(yargsMock.option).toHaveBeenCalledWith('project-name', expect.objectContaining({
|
|
42
|
+
type: 'string',
|
|
43
|
+
describe: expect.any(String),
|
|
44
|
+
}));
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CommonArgs, ConfigArgs, AccountArgs, EnvironmentArgs, YargsCommandModule, JSONOutputArgs } from '../../types/Yargs.js';
|
|
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;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { fetchDeveloperTestAccountOauthAppInstallStatus, installOauthAppIntoDeveloperTestAccount, } from '@hubspot/local-dev-lib/api/developerTestAccounts';
|
|
2
|
+
import { trackCommandUsage } from '../../lib/usageTracking.js';
|
|
3
|
+
import { commands } from '../../lang/en.js';
|
|
4
|
+
import { EXIT_CODES } from '../../lib/enums/exitCodes.js';
|
|
5
|
+
import { makeYargsBuilder } from '../../lib/yargsUtils.js';
|
|
6
|
+
import { APP_AUTH_TYPES } from '../../lib/constants.js';
|
|
7
|
+
import { uiLogger } from '../../lib/ui/logger.js';
|
|
8
|
+
import SpinniesManager from '../../lib/ui/SpinniesManager.js';
|
|
9
|
+
import { poll } from '../../lib/polling.js';
|
|
10
|
+
import { getProjectConfig, validateProjectConfig, } from '../../lib/projects/config.js';
|
|
11
|
+
import { handleTranslate } from '../../lib/projects/upload.js';
|
|
12
|
+
import { isAppIRNode } from '../../lib/projects/structure.js';
|
|
13
|
+
import { logError } from '../../lib/errorHandlers/index.js';
|
|
14
|
+
const command = 'install <test-account-id>';
|
|
15
|
+
const describe = undefined; // commands.app.subcommands.install.describe;
|
|
16
|
+
async function handler(args) {
|
|
17
|
+
const { derivedAccountId, appUid, projectName, testAccountId, formatOutputAsJson, } = args;
|
|
18
|
+
trackCommandUsage('app-install', {}, derivedAccountId);
|
|
19
|
+
const jsonOutput = {};
|
|
20
|
+
let targetProjectName = projectName;
|
|
21
|
+
let targetAppUid = appUid;
|
|
22
|
+
const { projectConfig, projectDir } = await getProjectConfig();
|
|
23
|
+
if (!targetProjectName) {
|
|
24
|
+
validateProjectConfig(projectConfig, projectDir);
|
|
25
|
+
targetProjectName = projectConfig?.name;
|
|
26
|
+
}
|
|
27
|
+
if (!targetProjectName) {
|
|
28
|
+
uiLogger.error(commands.app.subcommands.install.errors.mustSpecifyProjectName);
|
|
29
|
+
process.exit(EXIT_CODES.ERROR);
|
|
30
|
+
}
|
|
31
|
+
let isAppOauth = true;
|
|
32
|
+
if (!targetAppUid) {
|
|
33
|
+
const intermediateRepresentation = await handleTranslate(projectDir, projectConfig, derivedAccountId, true, undefined);
|
|
34
|
+
if (intermediateRepresentation) {
|
|
35
|
+
Object.values(intermediateRepresentation.intermediateNodesIndexedByUid).forEach(node => {
|
|
36
|
+
if (isAppIRNode(node)) {
|
|
37
|
+
targetAppUid = node.uid;
|
|
38
|
+
isAppOauth = node.config.auth.type === APP_AUTH_TYPES.OAUTH;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!targetAppUid) {
|
|
44
|
+
uiLogger.error(commands.app.subcommands.install.errors.noAppUidFound);
|
|
45
|
+
process.exit(EXIT_CODES.ERROR);
|
|
46
|
+
}
|
|
47
|
+
if (!isAppOauth) {
|
|
48
|
+
uiLogger.error(commands.app.subcommands.install.errors.appMustBeOauth);
|
|
49
|
+
process.exit(EXIT_CODES.ERROR);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const { data } = await installOauthAppIntoDeveloperTestAccount(derivedAccountId, testAccountId, targetProjectName, targetAppUid);
|
|
53
|
+
if (data?.authCodes.length > 0) {
|
|
54
|
+
jsonOutput.authCode = data.authCodes[0].authCode;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
logError(err);
|
|
59
|
+
process.exit(EXIT_CODES.ERROR);
|
|
60
|
+
}
|
|
61
|
+
SpinniesManager.init({
|
|
62
|
+
succeedColor: 'white',
|
|
63
|
+
});
|
|
64
|
+
SpinniesManager.add('installApp', {
|
|
65
|
+
text: commands.app.subcommands.install.polling.start,
|
|
66
|
+
});
|
|
67
|
+
let appInstallSucceeded = false;
|
|
68
|
+
try {
|
|
69
|
+
await poll(() => fetchDeveloperTestAccountOauthAppInstallStatus(derivedAccountId, targetProjectName, targetAppUid), {
|
|
70
|
+
successStates: ['SUCCESS'],
|
|
71
|
+
errorStates: [],
|
|
72
|
+
});
|
|
73
|
+
appInstallSucceeded = true;
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
SpinniesManager.fail('installApp');
|
|
77
|
+
logError(err);
|
|
78
|
+
process.exit(EXIT_CODES.ERROR);
|
|
79
|
+
}
|
|
80
|
+
if (!appInstallSucceeded) {
|
|
81
|
+
SpinniesManager.fail('installApp');
|
|
82
|
+
process.exit(EXIT_CODES.ERROR);
|
|
83
|
+
}
|
|
84
|
+
SpinniesManager.succeed('installApp', {
|
|
85
|
+
text: commands.app.subcommands.install.polling.success,
|
|
86
|
+
});
|
|
87
|
+
if (formatOutputAsJson) {
|
|
88
|
+
uiLogger.json(jsonOutput);
|
|
89
|
+
}
|
|
90
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
91
|
+
}
|
|
92
|
+
function installAppBuilder(yargs) {
|
|
93
|
+
yargs.positional('test-account-id', {
|
|
94
|
+
describe: commands.app.subcommands.install.positionals.testAccountId,
|
|
95
|
+
required: true,
|
|
96
|
+
type: 'number',
|
|
97
|
+
});
|
|
98
|
+
yargs.option('app-uid', {
|
|
99
|
+
describe: commands.app.subcommands.install.options.appUid,
|
|
100
|
+
type: 'string',
|
|
101
|
+
});
|
|
102
|
+
yargs.option('project-name', {
|
|
103
|
+
describe: commands.app.subcommands.install.options.projectName,
|
|
104
|
+
type: 'string',
|
|
105
|
+
});
|
|
106
|
+
yargs.example('install 1234567890 --app-uid=my-app-uid --project-name=my-project', commands.app.subcommands.install.example);
|
|
107
|
+
return yargs;
|
|
108
|
+
}
|
|
109
|
+
const builder = makeYargsBuilder(installAppBuilder, command, commands.app.subcommands.install.describe, {
|
|
110
|
+
useGlobalOptions: true,
|
|
111
|
+
useAccountOptions: true,
|
|
112
|
+
useConfigOptions: true,
|
|
113
|
+
useEnvironmentOptions: true,
|
|
114
|
+
useJSONOutputOptions: true,
|
|
115
|
+
});
|
|
116
|
+
const installAppCommand = {
|
|
117
|
+
command,
|
|
118
|
+
describe,
|
|
119
|
+
handler,
|
|
120
|
+
builder,
|
|
121
|
+
};
|
|
122
|
+
export default installAppCommand;
|
package/commands/app.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import migrateCommand from './app/migrate.js';
|
|
2
2
|
import appSecretCommand from './app/secret.js';
|
|
3
|
+
import installAppCommand from './app/install.js';
|
|
3
4
|
import { makeYargsBuilder } from '../lib/yargsUtils.js';
|
|
4
5
|
const command = ['app', 'apps'];
|
|
5
6
|
// Keep the command hidden for now
|
|
6
7
|
const describe = undefined;
|
|
7
8
|
function appBuilder(yargs) {
|
|
8
|
-
yargs
|
|
9
|
+
yargs
|
|
10
|
+
.command(migrateCommand)
|
|
11
|
+
.command(appSecretCommand)
|
|
12
|
+
.command(installAppCommand)
|
|
13
|
+
.demandCommand(1, '');
|
|
9
14
|
return yargs;
|
|
10
15
|
}
|
|
11
16
|
const builder = makeYargsBuilder(appBuilder, command, describe);
|
package/commands/getStarted.js
CHANGED
|
@@ -30,8 +30,6 @@ async function handler(args) {
|
|
|
30
30
|
const env = getEnv(derivedAccountId) === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD;
|
|
31
31
|
await trackCommandUsage('get-started', {}, derivedAccountId);
|
|
32
32
|
const accountName = uiAccountDescription(derivedAccountId);
|
|
33
|
-
// TODO: Put this in constants.ts once we have a defined place for the template before INBOUND
|
|
34
|
-
const templateSource = 'robrown-hubspot/hubspot-project-components-ua-app-objects-beta';
|
|
35
33
|
uiInfoSection(commands.getStarted.startTitle, () => {
|
|
36
34
|
uiLogger.log(commands.getStarted.startDescription);
|
|
37
35
|
uiLogger.log(commands.getStarted.guideOverview(accountName));
|
|
@@ -83,16 +81,7 @@ async function handler(args) {
|
|
|
83
81
|
else {
|
|
84
82
|
uiLogger.log(' ');
|
|
85
83
|
uiLogger.log(commands.getStarted.logs.appSelected);
|
|
86
|
-
// 1. Fetch project templates
|
|
87
|
-
let latestRepoReleaseTag;
|
|
88
84
|
const { dest, name } = await projectNameAndDestPrompt(args);
|
|
89
|
-
// Specific template for get-started command
|
|
90
|
-
const projectTemplate = {
|
|
91
|
-
name: 'private-app-get-started-template',
|
|
92
|
-
label: 'CRM getting started project with private apps',
|
|
93
|
-
path: 'projects/private-app-get-started-template',
|
|
94
|
-
};
|
|
95
|
-
// 3. Create the project files
|
|
96
85
|
const projectDest = path.resolve(getCwd(), dest);
|
|
97
86
|
const { projectConfig: existingProjectConfig, projectDir: existingProjectDir, } = await getProjectConfig(projectDest);
|
|
98
87
|
if (existingProjectConfig &&
|
|
@@ -107,13 +96,10 @@ async function handler(args) {
|
|
|
107
96
|
uiLogger.error(commands.project.create.errors.cannotNestProjects(existingProjectDir));
|
|
108
97
|
process.exit(EXIT_CODES.ERROR);
|
|
109
98
|
}
|
|
110
|
-
const repo = templateSource || HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH;
|
|
111
99
|
// 4. Clone the project template from GitHub
|
|
112
|
-
// This is temporary until we have the UA template in the main repo
|
|
113
100
|
try {
|
|
114
|
-
await cloneGithubRepo(
|
|
115
|
-
sourceDir:
|
|
116
|
-
tag: latestRepoReleaseTag,
|
|
101
|
+
await cloneGithubRepo(HUBSPOT_PROJECT_COMPONENTS_GITHUB_PATH, projectDest, {
|
|
102
|
+
sourceDir: '2025.2/private-app-get-started-template',
|
|
117
103
|
hideLogs: true,
|
|
118
104
|
});
|
|
119
105
|
await trackCommandMetadataUsage('get-started', {
|
|
@@ -109,7 +109,7 @@ export async function unifiedProjectDevFlow({ args, targetProjectAccountId, prov
|
|
|
109
109
|
let project = uploadedProject;
|
|
110
110
|
SpinniesManager.init();
|
|
111
111
|
if (projectExists && project) {
|
|
112
|
-
await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes);
|
|
112
|
+
await compareLocalProjectToDeployed(projectConfig, targetProjectAccountId, project.deployedBuild?.buildId, projectNodes, args.profile);
|
|
113
113
|
}
|
|
114
114
|
else {
|
|
115
115
|
project = await createNewProjectForLocalDev(projectConfig, targetProjectAccountId, false, false);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CommonArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
-
type ProjectUploadArgs = CommonArgs & JSONOutputArgs & {
|
|
1
|
+
import { CommonArgs, EnvironmentArgs, JSONOutputArgs, YargsCommandModule } from '../../types/Yargs.js';
|
|
2
|
+
type ProjectUploadArgs = CommonArgs & JSONOutputArgs & EnvironmentArgs & {
|
|
3
3
|
forceCreate: boolean;
|
|
4
4
|
message: string;
|
|
5
5
|
m: string;
|
|
@@ -25,7 +25,7 @@ async function handler(args) {
|
|
|
25
25
|
validateProjectConfig(projectConfig, projectDir);
|
|
26
26
|
let targetAccountId;
|
|
27
27
|
if (useV3Api(projectConfig.platformVersion)) {
|
|
28
|
-
targetAccountId = await loadAndValidateProfile(projectConfig, projectDir, profile);
|
|
28
|
+
targetAccountId = await loadAndValidateProfile(projectConfig, projectDir, profile, args.useEnv);
|
|
29
29
|
}
|
|
30
30
|
targetAccountId = targetAccountId || derivedAccountId;
|
|
31
31
|
const accountConfig = getAccountConfig(targetAccountId);
|
|
@@ -75,6 +75,9 @@ async function handler(args) {
|
|
|
75
75
|
resultJson.personalAccessKey = createResult.personalAccessKey;
|
|
76
76
|
}
|
|
77
77
|
catch (err) {
|
|
78
|
+
SpinniesManager.fail('createTestAccount', {
|
|
79
|
+
text: commands.testAccount.create.polling.createFailure,
|
|
80
|
+
});
|
|
78
81
|
logError(err);
|
|
79
82
|
SpinniesManager.fail('createTestAccount', {
|
|
80
83
|
text: commands.testAccount.create.polling.createFailure,
|
package/lang/en.d.ts
CHANGED
|
@@ -1553,6 +1553,28 @@ ${string}`;
|
|
|
1553
1553
|
readonly app: {
|
|
1554
1554
|
readonly describe: "Commands for managing apps.";
|
|
1555
1555
|
readonly subcommands: {
|
|
1556
|
+
readonly install: {
|
|
1557
|
+
readonly describe: "Install an OAuth app into a test account.";
|
|
1558
|
+
readonly options: {
|
|
1559
|
+
readonly appUid: "The uid of the app to install";
|
|
1560
|
+
readonly projectName: "The name of the project that contains the app";
|
|
1561
|
+
};
|
|
1562
|
+
readonly positionals: {
|
|
1563
|
+
readonly testAccountId: "The id of the test account to install the app into";
|
|
1564
|
+
};
|
|
1565
|
+
readonly errors: {
|
|
1566
|
+
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.`;
|
|
1567
|
+
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.`;
|
|
1568
|
+
readonly appMustBeOauth: "This command only supports installing oauth apps. Please specify an app with oauth auth type.";
|
|
1569
|
+
};
|
|
1570
|
+
readonly polling: {
|
|
1571
|
+
readonly start: "Installing app...";
|
|
1572
|
+
readonly success: "App installed successfully";
|
|
1573
|
+
readonly failure: "App installation failed";
|
|
1574
|
+
readonly error: "Error installing app";
|
|
1575
|
+
};
|
|
1576
|
+
readonly example: "Install the app with uid my-app-uid from the project named \"my-project\" into the target account with id 1234567890";
|
|
1577
|
+
};
|
|
1556
1578
|
readonly secret: {
|
|
1557
1579
|
readonly describe: "Commands for managing secrets.";
|
|
1558
1580
|
readonly subcommands: {
|
|
@@ -2601,7 +2623,7 @@ export declare const lib: {
|
|
|
2601
2623
|
readonly checking: "Checking if your deployed build is up to date...";
|
|
2602
2624
|
readonly upToDate: "Deployed build is up to date.";
|
|
2603
2625
|
readonly notUpToDate: "Your project contains undeployed local changes.";
|
|
2604
|
-
readonly notUpToDateExplanation:
|
|
2626
|
+
readonly notUpToDateExplanation: (profile?: string) => string;
|
|
2605
2627
|
};
|
|
2606
2628
|
readonly createNewProjectForLocalDev: {
|
|
2607
2629
|
readonly projectMustExistExplanation: (projectName: string, accountId: number) => string;
|
package/lang/en.js
CHANGED
|
@@ -1550,6 +1550,28 @@ export const commands = {
|
|
|
1550
1550
|
app: {
|
|
1551
1551
|
describe: 'Commands for managing apps.',
|
|
1552
1552
|
subcommands: {
|
|
1553
|
+
install: {
|
|
1554
|
+
describe: 'Install an OAuth app into a test account.',
|
|
1555
|
+
options: {
|
|
1556
|
+
appUid: 'The uid of the app to install',
|
|
1557
|
+
projectName: 'The name of the project that contains the app',
|
|
1558
|
+
},
|
|
1559
|
+
positionals: {
|
|
1560
|
+
testAccountId: 'The id of the test account to install the app into',
|
|
1561
|
+
},
|
|
1562
|
+
errors: {
|
|
1563
|
+
mustSpecifyProjectName: `You must specify a project name. Use the ${uiCommandReference('--project-name')} flag to specify the project name or run this command from within a project directory.`,
|
|
1564
|
+
noAppUidFound: `No app uid found. Please specify the app uid with the ${uiCommandReference('--app-uid')} flag or run this command from within a project that contains an app.`,
|
|
1565
|
+
appMustBeOauth: 'This command only supports installing oauth apps. Please specify an app with oauth auth type.',
|
|
1566
|
+
},
|
|
1567
|
+
polling: {
|
|
1568
|
+
start: 'Installing app...',
|
|
1569
|
+
success: 'App installed successfully',
|
|
1570
|
+
failure: 'App installation failed',
|
|
1571
|
+
error: 'Error installing app',
|
|
1572
|
+
},
|
|
1573
|
+
example: 'Install the app with uid my-app-uid from the project named "my-project" into the target account with id 1234567890',
|
|
1574
|
+
},
|
|
1553
1575
|
secret: {
|
|
1554
1576
|
describe: 'Commands for managing secrets.',
|
|
1555
1577
|
subcommands: {
|
|
@@ -2598,7 +2620,7 @@ export const lib = {
|
|
|
2598
2620
|
checking: 'Checking if your deployed build is up to date...',
|
|
2599
2621
|
upToDate: 'Deployed build is up to date.',
|
|
2600
2622
|
notUpToDate: `Your project contains undeployed local changes.`,
|
|
2601
|
-
notUpToDateExplanation: `Run ${uiCommandReference(
|
|
2623
|
+
notUpToDateExplanation: (profile) => `Run ${uiCommandReference(`hs project upload ${profile ? `--profile ${profile}` : ''}`)} to upload these changes to HubSpot, then re-run ${uiCommandReference(`hs project dev ${profile ? `--profile ${profile}` : ''}`)} to continue local development.`,
|
|
2602
2624
|
},
|
|
2603
2625
|
createNewProjectForLocalDev: {
|
|
2604
2626
|
projectMustExistExplanation: (projectName, accountId) => `The project ${projectName} does not exist in the target account ${uiAccountDescription(accountId)}. This command requires the project to exist in the target account.`,
|
package/lib/mcp/setup.js
CHANGED
|
@@ -8,7 +8,7 @@ import path from 'path';
|
|
|
8
8
|
import os from 'os';
|
|
9
9
|
import fs from 'fs-extra';
|
|
10
10
|
import { existsSync } from 'fs';
|
|
11
|
-
const mcpServerName = '
|
|
11
|
+
const mcpServerName = 'HubSpot';
|
|
12
12
|
const claudeCode = 'claude';
|
|
13
13
|
const windsurf = 'windsurf';
|
|
14
14
|
const cursor = 'cursor';
|
package/lib/projectProfiles.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export declare function logProfileHeader(profileName: string): void;
|
|
|
4
4
|
export declare function logProfileFooter(profile: HsProfileFile, includeVariables?: boolean): void;
|
|
5
5
|
export declare function loadProfile(projectConfig: ProjectConfig | null, projectDir: string | null, profileName: string): HsProfileFile | undefined;
|
|
6
6
|
export declare function exitIfUsingProfiles(projectConfig: ProjectConfig | null, projectDir: string | null): Promise<void>;
|
|
7
|
-
export declare function loadAndValidateProfile(projectConfig: ProjectConfig | null, projectDir: string | null, argsProfile: string | undefined): Promise<number | undefined>;
|
|
7
|
+
export declare function loadAndValidateProfile(projectConfig: ProjectConfig | null, projectDir: string | null, argsProfile: string | undefined, useEnv?: boolean): Promise<number | undefined>;
|
package/lib/projectProfiles.js
CHANGED
|
@@ -38,7 +38,12 @@ export function loadProfile(projectConfig, projectDir, profileName) {
|
|
|
38
38
|
uiLogger.error(lib.projectProfiles.loadProfile.errors.missingAccountId(profileFilename));
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
|
-
return
|
|
41
|
+
return {
|
|
42
|
+
...profile,
|
|
43
|
+
accountId: process.env.HUBSPOT_ACCOUNT_ID
|
|
44
|
+
? Number(process.env.HUBSPOT_ACCOUNT_ID)
|
|
45
|
+
: profile.accountId,
|
|
46
|
+
};
|
|
42
47
|
}
|
|
43
48
|
catch (e) {
|
|
44
49
|
uiLogger.error(lib.projectProfiles.loadProfile.errors.failedToLoadProfile(profileFilename));
|
|
@@ -54,7 +59,7 @@ export async function exitIfUsingProfiles(projectConfig, projectDir) {
|
|
|
54
59
|
}
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
|
-
export async function loadAndValidateProfile(projectConfig, projectDir, argsProfile) {
|
|
62
|
+
export async function loadAndValidateProfile(projectConfig, projectDir, argsProfile, useEnv = false) {
|
|
58
63
|
if (argsProfile) {
|
|
59
64
|
logProfileHeader(argsProfile);
|
|
60
65
|
const profile = loadProfile(projectConfig, projectDir, argsProfile);
|
|
@@ -63,6 +68,9 @@ export async function loadAndValidateProfile(projectConfig, projectDir, argsProf
|
|
|
63
68
|
process.exit(EXIT_CODES.ERROR);
|
|
64
69
|
}
|
|
65
70
|
logProfileFooter(profile, true);
|
|
71
|
+
if (useEnv) {
|
|
72
|
+
return Number(process.env.HUBSPOT_ACCOUNT_ID);
|
|
73
|
+
}
|
|
66
74
|
return profile.accountId;
|
|
67
75
|
}
|
|
68
76
|
else {
|
|
@@ -6,7 +6,7 @@ export declare function createNewProjectForLocalDev(projectConfig: ProjectConfig
|
|
|
6
6
|
export declare function createInitialBuildForNewProject(projectConfig: ProjectConfig, projectDir: string, targetAccountId: number, sendIR?: boolean, profile?: string): Promise<Build>;
|
|
7
7
|
export declare function compareLocalProjectToDeployed(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number | undefined, localProjectNodes: {
|
|
8
8
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
9
|
-
}): Promise<void>;
|
|
9
|
+
}, profile?: string): Promise<void>;
|
|
10
10
|
export declare function isDeployedProjectUpToDateWithLocal(projectConfig: ProjectConfig, accountId: number, deployedBuildId: number, localProjectNodes: {
|
|
11
11
|
[key: string]: IntermediateRepresentationNodeLocalDev;
|
|
12
|
-
}): Promise<boolean>;
|
|
12
|
+
}, profile?: string): Promise<boolean>;
|
|
@@ -123,7 +123,7 @@ export async function createInitialBuildForNewProject(projectConfig, projectDir,
|
|
|
123
123
|
}
|
|
124
124
|
return initialUploadResult.buildResult;
|
|
125
125
|
}
|
|
126
|
-
export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes) {
|
|
126
|
+
export async function compareLocalProjectToDeployed(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
|
|
127
127
|
uiLogger.log('');
|
|
128
128
|
if (!deployedBuildId) {
|
|
129
129
|
uiLogger.error(lib.localDevHelpers.project.compareLocalProjectToDeployed.noDeployedBuild(projectConfig.name, uiAccountDescription(accountId)));
|
|
@@ -132,7 +132,7 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
|
|
|
132
132
|
SpinniesManager.add('compareLocalProjectToDeployed', {
|
|
133
133
|
text: lib.localDevHelpers.project.compareLocalProjectToDeployed.checking,
|
|
134
134
|
});
|
|
135
|
-
const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes);
|
|
135
|
+
const isUpToDate = await isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile);
|
|
136
136
|
if (isUpToDate) {
|
|
137
137
|
SpinniesManager.succeed('compareLocalProjectToDeployed', {
|
|
138
138
|
text: lib.localDevHelpers.project.compareLocalProjectToDeployed.upToDate,
|
|
@@ -144,12 +144,11 @@ export async function compareLocalProjectToDeployed(projectConfig, accountId, de
|
|
|
144
144
|
.notUpToDate,
|
|
145
145
|
});
|
|
146
146
|
uiLogger.log('');
|
|
147
|
-
uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed
|
|
148
|
-
.notUpToDateExplanation);
|
|
147
|
+
uiLogger.log(lib.localDevHelpers.project.compareLocalProjectToDeployed.notUpToDateExplanation(profile));
|
|
149
148
|
process.exit(EXIT_CODES.SUCCESS);
|
|
150
149
|
}
|
|
151
150
|
}
|
|
152
|
-
export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes) {
|
|
151
|
+
export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountId, deployedBuildId, localProjectNodes, profile) {
|
|
153
152
|
let tempDir = null;
|
|
154
153
|
try {
|
|
155
154
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'hubspot-project-compare-'));
|
|
@@ -161,7 +160,7 @@ export async function isDeployedProjectUpToDateWithLocal(projectConfig, accountI
|
|
|
161
160
|
projectSourceDir: deployedProjectSourceDir,
|
|
162
161
|
platformVersion: projectConfig.platformVersion,
|
|
163
162
|
accountId: accountId,
|
|
164
|
-
}, {});
|
|
163
|
+
}, { profile });
|
|
165
164
|
return isDeepEqual(localProjectNodes, deployedProjectNodes, ['localDev']);
|
|
166
165
|
}
|
|
167
166
|
finally {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ComponentTypes, Component, GenericComponentConfig, PublicAppComponentConfig, PrivateAppComponentConfig, AppCardComponentConfig } from '../../types/Projects.js';
|
|
2
|
-
import { IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types.js';
|
|
2
|
+
import { IntermediateRepresentationNode, IntermediateRepresentationNodeLocalDev } from '@hubspot/project-parsing-lib/src/lib/types.js';
|
|
3
3
|
import { AppIRNode } from '../../types/ProjectComponents.js';
|
|
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): component is AppIRNode;
|
|
18
|
+
export declare function isAppIRNode(component: IntermediateRepresentationNodeLocalDev | IntermediateRepresentationNode): component is AppIRNode;
|
package/lib/projects/upload.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FileResult } from 'tmp';
|
|
2
|
+
import { IntermediateRepresentation } from '@hubspot/project-parsing-lib';
|
|
2
3
|
import { ProjectConfig } from '../../types/Projects.js';
|
|
3
4
|
type ProjectUploadCallbackFunction<T> = (accountId: number, projectConfig: ProjectConfig, tempFile: FileResult, buildId: number) => Promise<T>;
|
|
4
5
|
type ProjectUploadResult<T> = {
|
|
@@ -20,5 +21,5 @@ type HandleProjectUploadArg<T> = {
|
|
|
20
21
|
export declare function handleProjectUpload<T>({ accountId, projectConfig, projectDir, callbackFunc, profile, uploadMessage, forceCreate, isUploadCommand, sendIR, skipValidation, }: HandleProjectUploadArg<T>): Promise<ProjectUploadResult<T>>;
|
|
21
22
|
export declare function validateSourceDirectory(srcDir: string, projectConfig: ProjectConfig): void;
|
|
22
23
|
export declare function validateNoHSMetaMismatch(srcDir: string, projectConfig: ProjectConfig): Promise<void>;
|
|
23
|
-
export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<
|
|
24
|
+
export declare function handleTranslate(projectDir: string, projectConfig: ProjectConfig, accountId: number, skipValidation: boolean, profile: string | undefined): Promise<IntermediateRepresentation | undefined>;
|
|
24
25
|
export {};
|
package/lib/projects/upload.js
CHANGED
|
@@ -31,7 +31,7 @@ const inputSchema = {
|
|
|
31
31
|
};
|
|
32
32
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
33
33
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
34
|
-
const toolName = 'create-
|
|
34
|
+
const toolName = 'create-cms-function';
|
|
35
35
|
export class HsCreateFunctionTool extends Tool {
|
|
36
36
|
constructor(mcpServer) {
|
|
37
37
|
super(mcpServer);
|
|
@@ -47,7 +47,7 @@ const inputSchema = {
|
|
|
47
47
|
};
|
|
48
48
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
49
49
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
50
|
-
const toolName = 'create-
|
|
50
|
+
const toolName = 'create-cms-module';
|
|
51
51
|
export class HsCreateModuleTool extends Tool {
|
|
52
52
|
constructor(mcpServer) {
|
|
53
53
|
super(mcpServer);
|
|
@@ -23,7 +23,7 @@ const inputSchema = {
|
|
|
23
23
|
};
|
|
24
24
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
25
25
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
26
|
-
const toolName = 'create-
|
|
26
|
+
const toolName = 'create-cms-template';
|
|
27
27
|
export class HsCreateTemplateTool extends Tool {
|
|
28
28
|
constructor(mcpServer) {
|
|
29
29
|
super(mcpServer);
|
|
@@ -26,7 +26,7 @@ const inputSchema = {
|
|
|
26
26
|
};
|
|
27
27
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
28
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
29
|
-
const toolName = 'get-
|
|
29
|
+
const toolName = 'get-cms-serverless-function-logs';
|
|
30
30
|
export class HsFunctionLogsTool extends Tool {
|
|
31
31
|
constructor(mcpServer) {
|
|
32
32
|
super(mcpServer);
|
|
@@ -69,7 +69,7 @@ export class HsFunctionLogsTool extends Tool {
|
|
|
69
69
|
register() {
|
|
70
70
|
return this.mcpServer.registerTool(toolName, {
|
|
71
71
|
title: 'Get HubSpot CMS serverless function logs for an endpoint',
|
|
72
|
-
description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-
|
|
72
|
+
description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-cms-serverless-functions to get the endpoint path.',
|
|
73
73
|
inputSchema,
|
|
74
74
|
}, this.handler);
|
|
75
75
|
}
|
|
@@ -18,7 +18,7 @@ const inputSchema = {
|
|
|
18
18
|
};
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
20
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
21
|
-
const toolName = 'list-
|
|
21
|
+
const toolName = 'list-cms-serverless-functions';
|
|
22
22
|
export class HsListFunctionsTool extends Tool {
|
|
23
23
|
constructor(mcpServer) {
|
|
24
24
|
super(mcpServer);
|
|
@@ -18,7 +18,7 @@ const inputSchema = {
|
|
|
18
18
|
};
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
20
20
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
21
|
-
const toolName = 'list-
|
|
21
|
+
const toolName = 'list-cms-remote-contents';
|
|
22
22
|
export class HsListTool extends Tool {
|
|
23
23
|
constructor(mcpServer) {
|
|
24
24
|
super(mcpServer);
|
|
@@ -28,7 +28,7 @@ describe('HsCreateFunctionTool', () => {
|
|
|
28
28
|
describe('register', () => {
|
|
29
29
|
it('should register the tool with the MCP server', () => {
|
|
30
30
|
const result = tool.register();
|
|
31
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-
|
|
31
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-function', {
|
|
32
32
|
title: 'Create HubSpot CMS Serverless Function',
|
|
33
33
|
description: `Creates a new HubSpot CMS serverless function using the hs create function command. Functions can be created non-interactively by specifying functionsFolder, filename, and endpointPath. Supports all HTTP methods (${HTTP_METHODS.join(', ')}).`,
|
|
34
34
|
inputSchema: expect.any(Object),
|
|
@@ -27,7 +27,7 @@ describe('HsCreateModuleTool', () => {
|
|
|
27
27
|
describe('register', () => {
|
|
28
28
|
it('should register the tool with the MCP server', () => {
|
|
29
29
|
const result = tool.register();
|
|
30
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-
|
|
30
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-module', {
|
|
31
31
|
title: 'Create HubSpot CMS Module',
|
|
32
32
|
description: 'Creates a new HubSpot CMS module using the hs create module command. Modules can be created non-interactively by specifying moduleLabel and other module options. You can create either HubL or React modules by setting the reactType parameter.',
|
|
33
33
|
inputSchema: expect.any(Object),
|
|
@@ -28,7 +28,7 @@ describe('HsCreateTemplateTool', () => {
|
|
|
28
28
|
describe('register', () => {
|
|
29
29
|
it('should register the tool with the MCP server', () => {
|
|
30
30
|
const result = tool.register();
|
|
31
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-
|
|
31
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-cms-template', {
|
|
32
32
|
title: 'Create HubSpot CMS Template',
|
|
33
33
|
description: `Creates a new HubSpot CMS template using the hs create template command. Templates can be created non-interactively by specifying templateType. Supports all template types including: ${TEMPLATE_TYPES.join(', ')}.`,
|
|
34
34
|
inputSchema: expect.any(Object),
|
|
@@ -27,9 +27,9 @@ describe('HsFunctionLogsTool', () => {
|
|
|
27
27
|
describe('register', () => {
|
|
28
28
|
it('should register the tool with the MCP server', () => {
|
|
29
29
|
const result = tool.register();
|
|
30
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-
|
|
30
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-cms-serverless-function-logs', expect.objectContaining({
|
|
31
31
|
title: 'Get HubSpot CMS serverless function logs for an endpoint',
|
|
32
|
-
description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-
|
|
32
|
+
description: 'Retrieve logs for HubSpot CMS serverless functions. Use this tool to help debug issues with serverless functions by reading the production logs. Supports various options like latest, compact, and limiting results. Use after listing functions with list-cms-serverless-functions to get the endpoint path.',
|
|
33
33
|
inputSchema: expect.any(Object),
|
|
34
34
|
}), expect.any(Function));
|
|
35
35
|
expect(result).toBe(mockRegisteredTool);
|
|
@@ -27,7 +27,7 @@ describe('HsListFunctionsTool', () => {
|
|
|
27
27
|
describe('register', () => {
|
|
28
28
|
it('should register the tool with the MCP server', () => {
|
|
29
29
|
const result = tool.register();
|
|
30
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-
|
|
30
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-cms-serverless-functions', {
|
|
31
31
|
title: 'List HubSpot CMS Serverless Functions',
|
|
32
32
|
description: 'Get a list of all serverless functions deployed in a HubSpot portal/account. Shows function routes, HTTP methods, secrets, and timestamps.',
|
|
33
33
|
inputSchema: expect.any(Object),
|
|
@@ -27,7 +27,7 @@ describe('HsListTool', () => {
|
|
|
27
27
|
describe('register', () => {
|
|
28
28
|
it('should register the tool with the MCP server', () => {
|
|
29
29
|
const result = tool.register();
|
|
30
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-
|
|
30
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('list-cms-remote-contents', {
|
|
31
31
|
title: 'List HubSpot CMS Directory Contents',
|
|
32
32
|
description: 'List remote contents of a HubSpot CMS directory.',
|
|
33
33
|
inputSchema: expect.any(Object),
|
|
@@ -6,19 +6,19 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
6
6
|
addApp: z.ZodBoolean;
|
|
7
7
|
distribution: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"marketplace">, z.ZodLiteral<"private">]>>;
|
|
8
8
|
auth: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"static">, z.ZodLiteral<"oauth">]>>;
|
|
9
|
-
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<"scim">]>, "many">>;
|
|
9
|
+
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
10
|
}, "strip", z.ZodTypeAny, {
|
|
11
11
|
absoluteProjectPath: string;
|
|
12
12
|
addApp: boolean;
|
|
13
13
|
auth?: "oauth" | "static" | undefined;
|
|
14
14
|
distribution?: "marketplace" | "private" | undefined;
|
|
15
|
-
features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
15
|
+
features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
16
16
|
}, {
|
|
17
17
|
absoluteProjectPath: string;
|
|
18
18
|
addApp: boolean;
|
|
19
19
|
auth?: "oauth" | "static" | undefined;
|
|
20
20
|
distribution?: "marketplace" | "private" | undefined;
|
|
21
|
-
features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
21
|
+
features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
22
22
|
}>;
|
|
23
23
|
export type AddFeatureInputSchema = z.infer<typeof inputSchemaZodObject>;
|
|
24
24
|
export declare class AddFeatureToProjectTool extends Tool<AddFeatureInputSchema> {
|
|
@@ -16,20 +16,20 @@ const inputSchema = {
|
|
|
16
16
|
z.literal(APP_DISTRIBUTION_TYPES.MARKETPLACE),
|
|
17
17
|
z.literal(APP_DISTRIBUTION_TYPES.PRIVATE),
|
|
18
18
|
]))
|
|
19
|
-
.describe('
|
|
19
|
+
.describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Private is used if you do not wish to distribute your application on the HubSpot marketplace. '),
|
|
20
20
|
auth: z
|
|
21
21
|
.optional(z.union([
|
|
22
22
|
z.literal(APP_AUTH_TYPES.STATIC),
|
|
23
23
|
z.literal(APP_AUTH_TYPES.OAUTH),
|
|
24
24
|
]))
|
|
25
|
-
.describe('
|
|
25
|
+
.describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Static uses a static non changing authentication token, and is only available for private distribution. '),
|
|
26
26
|
features,
|
|
27
27
|
};
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
29
29
|
const inputSchemaZodObject = z.object({
|
|
30
30
|
...inputSchema,
|
|
31
31
|
});
|
|
32
|
-
const toolName = 'add-feature-to-
|
|
32
|
+
const toolName = 'add-feature-to-project';
|
|
33
33
|
export class AddFeatureToProjectTool extends Tool {
|
|
34
34
|
constructor(mcpServer) {
|
|
35
35
|
super(mcpServer);
|
|
@@ -8,7 +8,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
8
8
|
projectBase: z.ZodUnion<[z.ZodLiteral<"empty">, z.ZodLiteral<"app">]>;
|
|
9
9
|
distribution: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"marketplace">, z.ZodLiteral<"private">]>>;
|
|
10
10
|
auth: z.ZodOptional<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"static">, z.ZodLiteral<"oauth">]>>>;
|
|
11
|
-
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<"scim">]>, "many">>;
|
|
11
|
+
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">>;
|
|
12
12
|
}, "strip", z.ZodTypeAny, {
|
|
13
13
|
projectBase: "app" | "empty";
|
|
14
14
|
absoluteCurrentWorkingDirectory: string;
|
|
@@ -16,7 +16,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
16
16
|
name?: string | undefined;
|
|
17
17
|
auth?: "oauth" | "static" | undefined;
|
|
18
18
|
distribution?: "marketplace" | "private" | undefined;
|
|
19
|
-
features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
19
|
+
features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
20
20
|
}, {
|
|
21
21
|
projectBase: "app" | "empty";
|
|
22
22
|
absoluteCurrentWorkingDirectory: string;
|
|
@@ -24,7 +24,7 @@ declare const inputSchemaZodObject: z.ZodObject<{
|
|
|
24
24
|
name?: string | undefined;
|
|
25
25
|
auth?: "oauth" | "static" | undefined;
|
|
26
26
|
distribution?: "marketplace" | "private" | undefined;
|
|
27
|
-
features?: ("card" | "settings" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
27
|
+
features?: ("card" | "page" | "settings" | "app-event" | "workflow-action-tool" | "workflow-action" | "app-function" | "webhooks" | "app-object" | "scim")[] | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
export type CreateProjectInputSchema = z.infer<typeof inputSchemaZodObject>;
|
|
30
30
|
export declare class CreateProjectTool extends Tool<CreateProjectInputSchema> {
|
|
@@ -10,11 +10,11 @@ const inputSchema = {
|
|
|
10
10
|
absoluteCurrentWorkingDirectory,
|
|
11
11
|
name: z
|
|
12
12
|
.string()
|
|
13
|
-
.describe('The name of the project to be created. This name is how your project will appear in HubSpot.
|
|
13
|
+
.describe('If not specified by the user, DO NOT choose for them. Changing this is potentially destructive.The name of the project to be created. This name is how your project will appear in HubSpot. ')
|
|
14
14
|
.optional(),
|
|
15
15
|
destination: z
|
|
16
16
|
.string()
|
|
17
|
-
.describe('
|
|
17
|
+
.describe('DO NOT use the current directory unless the user has explicitly stated to do so. Relative path to the directory the project will be created in.'),
|
|
18
18
|
projectBase: z
|
|
19
19
|
.union([z.literal(EMPTY_PROJECT), z.literal(PROJECT_WITH_APP)])
|
|
20
20
|
.describe('Empty will create an empty project, and app will create a project with an app inside of it.'),
|
|
@@ -23,19 +23,19 @@ const inputSchema = {
|
|
|
23
23
|
z.literal(APP_DISTRIBUTION_TYPES.MARKETPLACE),
|
|
24
24
|
z.literal(APP_DISTRIBUTION_TYPES.PRIVATE),
|
|
25
25
|
]))
|
|
26
|
-
.describe('
|
|
26
|
+
.describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Private is used if you do not wish to distribute your application on the HubSpot marketplace. '),
|
|
27
27
|
auth: z
|
|
28
28
|
.optional(z.union([
|
|
29
29
|
z.literal(APP_AUTH_TYPES.STATIC),
|
|
30
30
|
z.literal(APP_AUTH_TYPES.OAUTH),
|
|
31
31
|
]))
|
|
32
|
-
.describe('
|
|
32
|
+
.describe('If not specified by the user, DO NOT choose for them. This cannot be changed after a project is uploaded. Static uses a static non changing authentication token, and is only available for private distribution. ')
|
|
33
33
|
.optional(),
|
|
34
34
|
features,
|
|
35
35
|
};
|
|
36
36
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
37
37
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
38
|
-
const toolName = 'create-
|
|
38
|
+
const toolName = 'create-project';
|
|
39
39
|
export class CreateProjectTool extends Tool {
|
|
40
40
|
constructor(mcpServer) {
|
|
41
41
|
super(mcpServer);
|
|
@@ -15,7 +15,7 @@ const inputSchema = {
|
|
|
15
15
|
const inputSchemaZodObject = z.object({
|
|
16
16
|
...inputSchema,
|
|
17
17
|
});
|
|
18
|
-
const toolName = 'deploy-
|
|
18
|
+
const toolName = 'deploy-project';
|
|
19
19
|
export class DeployProjectTool extends Tool {
|
|
20
20
|
constructor(mcpServer) {
|
|
21
21
|
super(mcpServer);
|
|
@@ -12,7 +12,7 @@ const inputSchema = {
|
|
|
12
12
|
const inputSchemaZodObject = z.object({
|
|
13
13
|
...inputSchema,
|
|
14
14
|
});
|
|
15
|
-
const toolName = 'fetch-
|
|
15
|
+
const toolName = 'fetch-doc';
|
|
16
16
|
export class DocFetchTool extends Tool {
|
|
17
17
|
constructor(mcpServer) {
|
|
18
18
|
super(mcpServer);
|
|
@@ -42,7 +42,7 @@ export class DocFetchTool extends Tool {
|
|
|
42
42
|
register() {
|
|
43
43
|
return this.mcpServer.registerTool(toolName, {
|
|
44
44
|
title: 'Fetch HubSpot Developer Documentation (single file)',
|
|
45
|
-
description: 'Always use this immediately after `search-
|
|
45
|
+
description: 'Always use this immediately after `search-docs` and before creating a plan, writing code, or answering technical questions. This tool retrieves the full, authoritative content of a HubSpot Developer Documentation page from its URL, ensuring responses are accurate, up-to-date, and grounded in the official docs.',
|
|
46
46
|
inputSchema,
|
|
47
47
|
}, this.handler);
|
|
48
48
|
}
|
|
@@ -13,7 +13,7 @@ const inputSchema = {
|
|
|
13
13
|
const inputSchemaZodObject = z.object({
|
|
14
14
|
...inputSchema,
|
|
15
15
|
});
|
|
16
|
-
const toolName = 'search-
|
|
16
|
+
const toolName = 'search-docs';
|
|
17
17
|
export class DocsSearchTool extends Tool {
|
|
18
18
|
constructor(mcpServer) {
|
|
19
19
|
super(mcpServer);
|
|
@@ -55,7 +55,7 @@ export class DocsSearchTool extends Tool {
|
|
|
55
55
|
register() {
|
|
56
56
|
return this.mcpServer.registerTool(toolName, {
|
|
57
57
|
title: 'Search HubSpot Developer Documentation',
|
|
58
|
-
description: 'Use this first whenever you need details about HubSpot APIs, SDKs, integrations, or developer platform features. This searches the official HubSpot Developer Documentation and returns the most relevant pages, each with a URL for use in `fetch-
|
|
58
|
+
description: 'Use this first whenever you need details about HubSpot APIs, SDKs, integrations, or developer platform features. This searches the official HubSpot Developer Documentation and returns the most relevant pages, each with a URL for use in `fetch-doc`. Always follow this with a fetch to get the full, authoritative content before making plans or writing answers.',
|
|
59
59
|
inputSchema,
|
|
60
60
|
}, this.handler);
|
|
61
61
|
}
|
|
@@ -16,7 +16,7 @@ const inputSchema = {
|
|
|
16
16
|
const inputSchemaZodObject = z.object({
|
|
17
17
|
...inputSchema,
|
|
18
18
|
});
|
|
19
|
-
const toolName = 'get-
|
|
19
|
+
const toolName = 'get-feature-config-schema';
|
|
20
20
|
export class GetConfigValuesTool extends Tool {
|
|
21
21
|
constructor(mcpServer) {
|
|
22
22
|
super(mcpServer);
|
|
@@ -24,7 +24,7 @@ const inputSchema = {
|
|
|
24
24
|
const inputSchemaZodObject = z.object({
|
|
25
25
|
...inputSchema,
|
|
26
26
|
});
|
|
27
|
-
const toolName = 'guided-walkthrough-
|
|
27
|
+
const toolName = 'guided-walkthrough-cli';
|
|
28
28
|
export class GuidedWalkthroughTool extends Tool {
|
|
29
29
|
constructor(mcpServer) {
|
|
30
30
|
super(mcpServer);
|
|
@@ -11,7 +11,7 @@ const inputSchema = {
|
|
|
11
11
|
const inputSchemaZodObject = z.object({
|
|
12
12
|
...inputSchema,
|
|
13
13
|
});
|
|
14
|
-
const toolName = 'upload-
|
|
14
|
+
const toolName = 'upload-project';
|
|
15
15
|
export class UploadProjectTools extends Tool {
|
|
16
16
|
constructor(mcpServer) {
|
|
17
17
|
super(mcpServer);
|
|
@@ -24,7 +24,7 @@ export class UploadProjectTools extends Tool {
|
|
|
24
24
|
register() {
|
|
25
25
|
return this.mcpServer.registerTool(toolName, {
|
|
26
26
|
title: 'Upload HubSpot Project',
|
|
27
|
-
description: 'Uploads the HubSpot project in current working directory. If the project does not exist, it will be created. MUST be ran from within the project directory.
|
|
27
|
+
description: 'DO NOT run this tool unless the user specifies they would like to upload the project, it is potentially destructive. Uploads the HubSpot project in current working directory. If the project does not exist, it will be created. MUST be ran from within the project directory.',
|
|
28
28
|
inputSchema,
|
|
29
29
|
}, this.handler);
|
|
30
30
|
}
|
|
@@ -9,7 +9,7 @@ const inputSchema = {
|
|
|
9
9
|
};
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
11
|
const inputSchemaZodObject = z.object({ ...inputSchema });
|
|
12
|
-
const toolName = 'validate-
|
|
12
|
+
const toolName = 'validate-project';
|
|
13
13
|
export class ValidateProjectTool extends Tool {
|
|
14
14
|
constructor(mcpServer) {
|
|
15
15
|
super(mcpServer);
|
|
@@ -28,7 +28,7 @@ describe('mcp-server/tools/project/AddFeatureToProject', () => {
|
|
|
28
28
|
describe('register', () => {
|
|
29
29
|
it('should register tool with correct parameters', () => {
|
|
30
30
|
const result = tool.register();
|
|
31
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('add-feature-to-
|
|
31
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('add-feature-to-project', expect.objectContaining({
|
|
32
32
|
title: 'Add feature to HubSpot Project',
|
|
33
33
|
description: expect.stringContaining('Adds a feature to an existing HubSpot project'),
|
|
34
34
|
inputSchema: expect.any(Object),
|
|
@@ -29,7 +29,7 @@ describe('mcp-server/tools/project/CreateProjectTool', () => {
|
|
|
29
29
|
describe('register', () => {
|
|
30
30
|
it('should register tool with correct parameters', () => {
|
|
31
31
|
const result = tool.register();
|
|
32
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-
|
|
32
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('create-project', {
|
|
33
33
|
title: 'Create HubSpot Project',
|
|
34
34
|
description: 'Creates a HubSpot project with the provided name and outputs it in the provided destination',
|
|
35
35
|
inputSchema: expect.any(Object),
|
|
@@ -26,7 +26,7 @@ describe('mcp-server/tools/project/DeployProject', () => {
|
|
|
26
26
|
describe('register', () => {
|
|
27
27
|
it('should register tool with correct parameters', () => {
|
|
28
28
|
const result = tool.register();
|
|
29
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('deploy-
|
|
29
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('deploy-project', {
|
|
30
30
|
title: 'Deploy a build of HubSpot Project',
|
|
31
31
|
description: expect.stringContaining('Takes a build number and a project name and deploys that build of the project'),
|
|
32
32
|
inputSchema: expect.any(Object),
|
|
@@ -24,9 +24,9 @@ describe('mcp-server/tools/project/DocFetchTool', () => {
|
|
|
24
24
|
describe('register', () => {
|
|
25
25
|
it('should register tool with correct parameters', () => {
|
|
26
26
|
const result = tool.register();
|
|
27
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('fetch-
|
|
27
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('fetch-doc', {
|
|
28
28
|
title: 'Fetch HubSpot Developer Documentation (single file)',
|
|
29
|
-
description: 'Always use this immediately after `search-
|
|
29
|
+
description: 'Always use this immediately after `search-docs` and before creating a plan, writing code, or answering technical questions. This tool retrieves the full, authoritative content of a HubSpot Developer Documentation page from its URL, ensuring responses are accurate, up-to-date, and grounded in the official docs.',
|
|
30
30
|
inputSchema: expect.any(Object),
|
|
31
31
|
}, tool.handler);
|
|
32
32
|
expect(result).toBe(mockRegisteredTool);
|
|
@@ -27,9 +27,9 @@ describe('mcp-server/tools/project/DocsSearchTool', () => {
|
|
|
27
27
|
describe('register', () => {
|
|
28
28
|
it('should register tool with correct parameters', () => {
|
|
29
29
|
const result = tool.register();
|
|
30
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('search-
|
|
30
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('search-docs', {
|
|
31
31
|
title: 'Search HubSpot Developer Documentation',
|
|
32
|
-
description: 'Use this first whenever you need details about HubSpot APIs, SDKs, integrations, or developer platform features. This searches the official HubSpot Developer Documentation and returns the most relevant pages, each with a URL for use in `fetch-
|
|
32
|
+
description: 'Use this first whenever you need details about HubSpot APIs, SDKs, integrations, or developer platform features. This searches the official HubSpot Developer Documentation and returns the most relevant pages, each with a URL for use in `fetch-doc`. Always follow this with a fetch to get the full, authoritative content before making plans or writing answers.',
|
|
33
33
|
inputSchema: expect.any(Object),
|
|
34
34
|
}, tool.handler);
|
|
35
35
|
expect(result).toBe(mockRegisteredTool);
|
|
@@ -25,7 +25,7 @@ describe('mcp-server/tools/project/GetConfigValuesTool', () => {
|
|
|
25
25
|
describe('register', () => {
|
|
26
26
|
it('should register tool with correct parameters', () => {
|
|
27
27
|
const result = tool.register();
|
|
28
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-
|
|
28
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('get-feature-config-schema', {
|
|
29
29
|
title: 'Fetch the JSON Schema for component',
|
|
30
30
|
description: expect.stringContaining('Fetches and returns the JSON schema for the provided feature'),
|
|
31
31
|
inputSchema: expect.objectContaining({
|
|
@@ -21,7 +21,7 @@ describe('mcp-server/tools/project/GuidedWalkthroughTool', () => {
|
|
|
21
21
|
describe('register', () => {
|
|
22
22
|
it('should register tool with correct parameters', () => {
|
|
23
23
|
const result = tool.register();
|
|
24
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('guided-walkthrough-
|
|
24
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('guided-walkthrough-cli', {
|
|
25
25
|
title: 'Guided walkthrough of the CLI',
|
|
26
26
|
description: 'Give the user a guided walkthrough of the HubSpot CLI.',
|
|
27
27
|
inputSchema: expect.any(Object),
|
|
@@ -21,7 +21,7 @@ describe('mcp-server/tools/project/UploadProjectTools', () => {
|
|
|
21
21
|
describe('register', () => {
|
|
22
22
|
it('should register tool with correct parameters', () => {
|
|
23
23
|
const result = tool.register();
|
|
24
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('upload-
|
|
24
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('upload-project', {
|
|
25
25
|
title: 'Upload HubSpot Project',
|
|
26
26
|
description: expect.stringContaining('Uploads the HubSpot project in current working directory.'),
|
|
27
27
|
inputSchema: expect.any(Object),
|
|
@@ -21,7 +21,7 @@ describe('mcp-server/tools/project/ValidateProjectTool', () => {
|
|
|
21
21
|
describe('register', () => {
|
|
22
22
|
it('should register tool with correct parameters', () => {
|
|
23
23
|
const result = tool.register();
|
|
24
|
-
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('validate-
|
|
24
|
+
expect(mockMcpServer.registerTool).toHaveBeenCalledWith('validate-project', {
|
|
25
25
|
title: expect.stringContaining('Validate HubSpot Project'),
|
|
26
26
|
description: expect.stringContaining('Validates the HubSpot project and its configuration files.'),
|
|
27
27
|
inputSchema: expect.any(Object),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
export declare const absoluteProjectPath: z.ZodString;
|
|
3
3
|
export declare const absoluteCurrentWorkingDirectory: z.ZodString;
|
|
4
|
-
export declare const 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<"scim">]>, "many">>;
|
|
4
|
+
export declare const 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">>;
|
|
5
5
|
export declare const docsSearchQuery: z.ZodString;
|
|
6
6
|
export declare const docUrl: z.ZodString;
|
|
@@ -9,12 +9,18 @@ export const features = z
|
|
|
9
9
|
.array(z.union([
|
|
10
10
|
z.literal('card'),
|
|
11
11
|
z.literal('settings'),
|
|
12
|
-
z
|
|
12
|
+
z
|
|
13
|
+
.literal('app-function')
|
|
14
|
+
.describe('Also known as a public serverless function'),
|
|
13
15
|
z.literal('webhooks'),
|
|
14
|
-
z
|
|
15
|
-
|
|
16
|
+
z
|
|
17
|
+
.literal('workflow-action')
|
|
18
|
+
.describe('Also known as a custom workflow action.'),
|
|
19
|
+
z.literal('workflow-action-tool').describe('Also known as agent tools.'),
|
|
16
20
|
z.literal('app-object'),
|
|
21
|
+
z.literal('app-event'),
|
|
17
22
|
z.literal('scim'),
|
|
23
|
+
z.literal('page'),
|
|
18
24
|
]))
|
|
19
25
|
.describe('The features to include in the project, multiple options can be selected')
|
|
20
26
|
.optional();
|
package/package.json
CHANGED