@tanstack/cta-cli 0.10.0-alpha.18 → 0.10.0-alpha.20
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/dist/cli.js +90 -34
- package/dist/command-line.js +75 -0
- package/dist/mcp.js +170 -0
- package/dist/options.js +40 -328
- package/dist/types/cli.d.ts +3 -1
- package/dist/types/command-line.d.ts +3 -0
- package/dist/types/mcp.d.ts +7 -0
- package/dist/types/options.d.ts +3 -4
- package/dist/types/types.d.ts +4 -1
- package/dist/types/ui-environment.d.ts +1 -1
- package/dist/types/ui-prompts.d.ts +10 -0
- package/dist/types/utils.d.ts +3 -0
- package/dist/ui-environment.js +45 -42
- package/dist/ui-prompts.js +140 -0
- package/dist/utils.js +7 -0
- package/package.json +10 -6
- package/src/cli.ts +115 -50
- package/src/command-line.ts +111 -0
- package/src/mcp.ts +247 -0
- package/src/options.ts +70 -394
- package/src/types.ts +5 -1
- package/src/ui-environment.ts +52 -44
- package/src/ui-prompts.ts +187 -0
- package/src/utils.ts +11 -0
- package/tests/command-line.test.ts +205 -0
- package/tests/index.test.ts +9 -0
- package/tests/options.test.ts +287 -0
- package/tests/setupVitest.ts +6 -0
- package/tests/ui-environment.test.ts +97 -0
- package/tests/ui-prompts.test.ts +233 -0
- package/vitest.config.js +7 -0
package/dist/cli.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
1
2
|
import { Command, InvalidArgumentError } from 'commander';
|
|
2
3
|
import { intro, log } from '@clack/prompts';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
|
-
import { SUPPORTED_PACKAGE_MANAGERS, addToApp, createApp, getAllAddOns, getFrameworkById, getFrameworkByName, getFrameworks, } from '@tanstack/cta-engine';
|
|
5
|
-
import { initAddOn } from '@tanstack/cta-custom-add-on';
|
|
6
|
-
import { runMCPServer } from '@tanstack/cta-mcp';
|
|
5
|
+
import { SUPPORTED_PACKAGE_MANAGERS, addToApp, compileAddOn, compileStarter, createApp, createSerializedOptions, getAllAddOns, getFrameworkById, getFrameworkByName, getFrameworks, initAddOn, initStarter, } from '@tanstack/cta-engine';
|
|
7
6
|
import { launchUI } from '@tanstack/cta-ui';
|
|
8
|
-
import {
|
|
7
|
+
import { runMCPServer } from './mcp.js';
|
|
8
|
+
import { promptForOptions } from './options.js';
|
|
9
|
+
import { normalizeOptions } from './command-line.js';
|
|
9
10
|
import { createUIEnvironment } from './ui-environment.js';
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
import { convertTemplateToMode } from './utils.js';
|
|
12
|
+
async function listAddOns(options, { forcedMode, forcedAddOns, defaultTemplate, }) {
|
|
13
|
+
const addOns = await getAllAddOns(getFrameworkById(options.framework || 'react-cra'), forcedMode ||
|
|
14
|
+
convertTemplateToMode(options.template || defaultTemplate || 'javascript'));
|
|
12
15
|
for (const addOn of addOns.filter((a) => !forcedAddOns.includes(a.id))) {
|
|
13
16
|
console.log(`${chalk.bold(addOn.id)}: ${addOn.description}`);
|
|
14
17
|
}
|
|
15
18
|
}
|
|
16
|
-
export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
17
|
-
const environment = createUIEnvironment();
|
|
19
|
+
export function cli({ name, appName, forcedMode, forcedAddOns = [], defaultTemplate = 'javascript', }) {
|
|
20
|
+
const environment = createUIEnvironment(appName, false);
|
|
18
21
|
const program = new Command();
|
|
19
22
|
const availableFrameworks = getFrameworks().map((f) => f.name);
|
|
20
23
|
const toolchains = new Set();
|
|
@@ -28,30 +31,56 @@ export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
|
28
31
|
program.name(name).description(`CLI to create a new ${appName} application`);
|
|
29
32
|
program
|
|
30
33
|
.command('add')
|
|
31
|
-
.argument('add-on', 'Name of the add-
|
|
32
|
-
.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
.argument('[add-on...]', 'Name of the add-ons (or add-ons separated by spaces or commas)')
|
|
35
|
+
.option('--forced', 'Force the add-on to be added', false)
|
|
36
|
+
.option('--ui', 'Add with the UI')
|
|
37
|
+
.action(async (addOns) => {
|
|
38
|
+
const parsedAddOns = [];
|
|
39
|
+
for (const addOn of addOns) {
|
|
40
|
+
if (addOn.includes(',') || addOn.includes(' ')) {
|
|
41
|
+
parsedAddOns.push(...addOn.split(/[\s,]+/).map((addon) => addon.trim()));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
parsedAddOns.push(addOn.trim());
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (program.opts().ui) {
|
|
48
|
+
launchUI({
|
|
49
|
+
mode: 'add',
|
|
50
|
+
addOns: parsedAddOns,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
await addToApp(environment, parsedAddOns, process.cwd(), {
|
|
55
|
+
forced: program.opts().forced,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
36
58
|
});
|
|
37
59
|
const addOnCommand = program.command('add-on');
|
|
38
60
|
addOnCommand
|
|
39
|
-
.command('
|
|
40
|
-
.description('
|
|
61
|
+
.command('init')
|
|
62
|
+
.description('Initialize an add-on from the current project')
|
|
41
63
|
.action(async () => {
|
|
42
|
-
await initAddOn(
|
|
64
|
+
await initAddOn(environment);
|
|
43
65
|
});
|
|
44
66
|
addOnCommand
|
|
45
|
-
.command('
|
|
46
|
-
.description('
|
|
67
|
+
.command('compile')
|
|
68
|
+
.description('Update add-on from the current project')
|
|
47
69
|
.action(async () => {
|
|
48
|
-
|
|
70
|
+
await compileAddOn(environment);
|
|
49
71
|
});
|
|
50
|
-
program
|
|
51
|
-
|
|
52
|
-
.
|
|
72
|
+
const starterCommand = program.command('starter');
|
|
73
|
+
starterCommand
|
|
74
|
+
.command('init')
|
|
75
|
+
.description('Initialize a project starter from the current project')
|
|
53
76
|
.action(async () => {
|
|
54
|
-
await
|
|
77
|
+
await initStarter(environment);
|
|
78
|
+
});
|
|
79
|
+
starterCommand
|
|
80
|
+
.command('compile')
|
|
81
|
+
.description('Compile the starter JSON file for the current project')
|
|
82
|
+
.action(async () => {
|
|
83
|
+
await compileStarter(environment);
|
|
55
84
|
});
|
|
56
85
|
program.argument('[project-name]', 'name of the project');
|
|
57
86
|
if (!forcedMode) {
|
|
@@ -84,6 +113,7 @@ export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
|
84
113
|
}
|
|
85
114
|
return value;
|
|
86
115
|
})
|
|
116
|
+
.option('--interactive', 'interactive mode', false)
|
|
87
117
|
.option('--tailwind', 'add Tailwind CSS', false)
|
|
88
118
|
.option('--add-ons [...add-ons]', 'pick from a list of available add-ons (comma separated list)', (value) => {
|
|
89
119
|
let addOns = !!value;
|
|
@@ -96,17 +126,19 @@ export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
|
96
126
|
.option('--no-git', 'do not create a git repository')
|
|
97
127
|
.option('--target-dir <path>', 'the target directory for the application root')
|
|
98
128
|
.option('--mcp', 'run the MCP server', false)
|
|
99
|
-
.option('--mcp-sse', 'run the MCP server in SSE mode', false)
|
|
129
|
+
.option('--mcp-sse', 'run the MCP server in SSE mode', false)
|
|
130
|
+
.option('--ui', 'Add with the UI');
|
|
100
131
|
program.action(async (projectName, options) => {
|
|
101
132
|
if (options.listAddOns) {
|
|
102
133
|
await listAddOns(options, {
|
|
103
|
-
forcedMode
|
|
134
|
+
forcedMode,
|
|
104
135
|
forcedAddOns,
|
|
136
|
+
defaultTemplate,
|
|
105
137
|
});
|
|
106
138
|
}
|
|
107
139
|
else if (options.mcp || options.mcpSse) {
|
|
108
140
|
await runMCPServer(!!options.mcpSse, {
|
|
109
|
-
forcedMode
|
|
141
|
+
forcedMode,
|
|
110
142
|
forcedAddOns,
|
|
111
143
|
appName,
|
|
112
144
|
});
|
|
@@ -121,23 +153,47 @@ export function cli({ name, appName, forcedMode, forcedAddOns, }) {
|
|
|
121
153
|
if (forcedMode) {
|
|
122
154
|
cliOptions.template = forcedMode;
|
|
123
155
|
}
|
|
124
|
-
let finalOptions
|
|
156
|
+
let finalOptions;
|
|
157
|
+
if (cliOptions.interactive) {
|
|
158
|
+
cliOptions.addOns = true;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
finalOptions = await normalizeOptions(cliOptions, forcedMode, forcedAddOns);
|
|
162
|
+
}
|
|
163
|
+
if (options.ui) {
|
|
164
|
+
const defaultOptions = {
|
|
165
|
+
framework: getFrameworkById(cliOptions.framework || 'react-cra'),
|
|
166
|
+
mode: 'file-router',
|
|
167
|
+
chosenAddOns: [],
|
|
168
|
+
packageManager: 'pnpm',
|
|
169
|
+
projectName: projectName || 'my-app',
|
|
170
|
+
targetDir: resolve(process.cwd(), projectName || 'my-app'),
|
|
171
|
+
typescript: true,
|
|
172
|
+
tailwind: true,
|
|
173
|
+
git: true,
|
|
174
|
+
};
|
|
175
|
+
launchUI({
|
|
176
|
+
mode: 'setup',
|
|
177
|
+
options: createSerializedOptions(finalOptions || defaultOptions),
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
125
181
|
if (finalOptions) {
|
|
126
182
|
intro(`Creating a new ${appName} app in ${projectName}...`);
|
|
127
183
|
}
|
|
128
184
|
else {
|
|
129
185
|
intro(`Let's configure your ${appName} application`);
|
|
130
186
|
finalOptions = await promptForOptions(cliOptions, {
|
|
131
|
-
forcedMode
|
|
187
|
+
forcedMode,
|
|
132
188
|
forcedAddOns,
|
|
133
189
|
});
|
|
134
190
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
191
|
+
if (!finalOptions) {
|
|
192
|
+
throw new Error('No options were provided');
|
|
193
|
+
}
|
|
194
|
+
finalOptions.targetDir =
|
|
195
|
+
options.targetDir || resolve(process.cwd(), finalOptions.projectName);
|
|
196
|
+
await createApp(environment, finalOptions);
|
|
141
197
|
}
|
|
142
198
|
catch (error) {
|
|
143
199
|
log.error(error instanceof Error ? error.message : 'An unknown error occurred');
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { CODE_ROUTER, DEFAULT_PACKAGE_MANAGER, FILE_ROUTER, finalizeAddOns, getFrameworkById, getPackageManager, loadStarter, } from '@tanstack/cta-engine';
|
|
3
|
+
export async function normalizeOptions(cliOptions, forcedMode, forcedAddOns) {
|
|
4
|
+
const projectName = (cliOptions.projectName ?? '').trim();
|
|
5
|
+
if (!projectName) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
let typescript = cliOptions.template === 'typescript' ||
|
|
9
|
+
cliOptions.template === 'file-router' ||
|
|
10
|
+
cliOptions.framework === 'solid';
|
|
11
|
+
let tailwind = !!cliOptions.tailwind;
|
|
12
|
+
if (cliOptions.framework === 'solid') {
|
|
13
|
+
tailwind = true;
|
|
14
|
+
}
|
|
15
|
+
let mode = forcedMode || cliOptions.template === 'file-router'
|
|
16
|
+
? FILE_ROUTER
|
|
17
|
+
: CODE_ROUTER;
|
|
18
|
+
const starter = cliOptions.starter
|
|
19
|
+
? await loadStarter(cliOptions.starter)
|
|
20
|
+
: undefined;
|
|
21
|
+
if (starter) {
|
|
22
|
+
tailwind = starter.tailwind;
|
|
23
|
+
typescript = starter.typescript;
|
|
24
|
+
cliOptions.framework = starter.framework;
|
|
25
|
+
mode = starter.mode;
|
|
26
|
+
}
|
|
27
|
+
const framework = getFrameworkById(cliOptions.framework || 'react-cra');
|
|
28
|
+
async function selectAddOns() {
|
|
29
|
+
// Edge case for Windows Powershell
|
|
30
|
+
if (Array.isArray(cliOptions.addOns) && cliOptions.addOns.length === 1) {
|
|
31
|
+
const parseSeparatedArgs = cliOptions.addOns[0].split(' ');
|
|
32
|
+
if (parseSeparatedArgs.length > 1) {
|
|
33
|
+
cliOptions.addOns = parseSeparatedArgs;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(cliOptions.addOns) ||
|
|
37
|
+
starter?.dependsOn ||
|
|
38
|
+
forcedAddOns ||
|
|
39
|
+
cliOptions.toolchain) {
|
|
40
|
+
const selectedAddOns = new Set([
|
|
41
|
+
...(starter?.dependsOn || []),
|
|
42
|
+
...(forcedAddOns || []),
|
|
43
|
+
]);
|
|
44
|
+
if (cliOptions.addOns && Array.isArray(cliOptions.addOns)) {
|
|
45
|
+
for (const a of cliOptions.addOns) {
|
|
46
|
+
selectedAddOns.add(a);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (cliOptions.toolchain) {
|
|
50
|
+
selectedAddOns.add(cliOptions.toolchain);
|
|
51
|
+
}
|
|
52
|
+
return await finalizeAddOns(framework, mode, Array.from(selectedAddOns));
|
|
53
|
+
}
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
const chosenAddOns = await selectAddOns();
|
|
57
|
+
if (chosenAddOns.length) {
|
|
58
|
+
tailwind = true;
|
|
59
|
+
typescript = true;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
projectName: projectName,
|
|
63
|
+
targetDir: resolve(process.cwd(), projectName),
|
|
64
|
+
framework,
|
|
65
|
+
mode,
|
|
66
|
+
typescript,
|
|
67
|
+
tailwind,
|
|
68
|
+
packageManager: cliOptions.packageManager ||
|
|
69
|
+
getPackageManager() ||
|
|
70
|
+
DEFAULT_PACKAGE_MANAGER,
|
|
71
|
+
git: !!cliOptions.git,
|
|
72
|
+
chosenAddOns,
|
|
73
|
+
starter: starter,
|
|
74
|
+
};
|
|
75
|
+
}
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import express from 'express';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { createApp, createDefaultEnvironment, finalizeAddOns, getFrameworkById, } from '@tanstack/cta-engine';
|
|
7
|
+
function createServer({ appName, forcedAddOns = [], }) {
|
|
8
|
+
const server = new McpServer({
|
|
9
|
+
name: `${appName} Application Builder`,
|
|
10
|
+
version: '1.0.0',
|
|
11
|
+
});
|
|
12
|
+
server.tool('listTanStackReactAddOns', 'List the available add-ons for creating TanStack React applications', {}, () => {
|
|
13
|
+
const framework = getFrameworkById('react-cra');
|
|
14
|
+
return {
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: 'text',
|
|
18
|
+
text: JSON.stringify(framework
|
|
19
|
+
.getAddOns()
|
|
20
|
+
.filter((addOn) => addOn.modes.includes('file-router'))
|
|
21
|
+
.map((addOn) => ({
|
|
22
|
+
id: addOn.id,
|
|
23
|
+
description: addOn.description,
|
|
24
|
+
}))),
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
server.tool('createTanStackReactApplication', 'Create a new TanStack React application', {
|
|
30
|
+
projectName: z
|
|
31
|
+
.string()
|
|
32
|
+
.describe('The package.json module name of the application (will also be the directory name)'),
|
|
33
|
+
cwd: z.string().describe('The directory to create the application in'),
|
|
34
|
+
addOns: z.array(z.string()).describe('The IDs of the add-ons to install'),
|
|
35
|
+
targetDir: z
|
|
36
|
+
.string()
|
|
37
|
+
.describe('The directory to create the application in. Use the absolute path of the directory you want the application to be created in'),
|
|
38
|
+
}, async ({ projectName, addOns, cwd, targetDir }) => {
|
|
39
|
+
const framework = getFrameworkById('react-cra');
|
|
40
|
+
try {
|
|
41
|
+
process.chdir(cwd);
|
|
42
|
+
try {
|
|
43
|
+
const chosenAddOns = await finalizeAddOns(framework, 'file-router', Array.from(new Set([
|
|
44
|
+
...addOns,
|
|
45
|
+
...forcedAddOns,
|
|
46
|
+
])));
|
|
47
|
+
await createApp(createDefaultEnvironment(), {
|
|
48
|
+
projectName: projectName.replace(/^\//, './'),
|
|
49
|
+
targetDir,
|
|
50
|
+
framework,
|
|
51
|
+
typescript: true,
|
|
52
|
+
tailwind: true,
|
|
53
|
+
packageManager: 'pnpm',
|
|
54
|
+
mode: 'file-router',
|
|
55
|
+
chosenAddOns,
|
|
56
|
+
git: true,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(error);
|
|
61
|
+
return {
|
|
62
|
+
content: [
|
|
63
|
+
{ type: 'text', text: `Error creating application: ${error}` },
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
content: [{ type: 'text', text: 'Application created successfully' }],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{ type: 'text', text: `Error creating application: ${error}` },
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
server.tool('listTanStackSolidAddOns', 'List the available add-ons for creating TanStack Solid applications', {}, () => {
|
|
80
|
+
const framework = getFrameworkById('solid');
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: 'text',
|
|
85
|
+
text: JSON.stringify(framework
|
|
86
|
+
.getAddOns()
|
|
87
|
+
.filter((addOn) => addOn.modes.includes('file-router'))
|
|
88
|
+
.map((addOn) => ({
|
|
89
|
+
id: addOn.id,
|
|
90
|
+
description: addOn.description,
|
|
91
|
+
}))),
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
server.tool('createTanStackSolidApplication', 'Create a new TanStack Solid application', {
|
|
97
|
+
projectName: z
|
|
98
|
+
.string()
|
|
99
|
+
.describe('The package.json module name of the application (will also be the directory name)'),
|
|
100
|
+
cwd: z.string().describe('The directory to create the application in'),
|
|
101
|
+
addOns: z.array(z.string()).describe('The IDs of the add-ons to install'),
|
|
102
|
+
targetDir: z
|
|
103
|
+
.string()
|
|
104
|
+
.describe('The directory to create the application in. Use the absolute path of the directory you want the application to be created in'),
|
|
105
|
+
}, async ({ projectName, addOns, cwd, targetDir }) => {
|
|
106
|
+
const framework = getFrameworkById('solid');
|
|
107
|
+
try {
|
|
108
|
+
process.chdir(cwd);
|
|
109
|
+
try {
|
|
110
|
+
const chosenAddOns = await finalizeAddOns(framework, 'file-router', Array.from(new Set([
|
|
111
|
+
...addOns,
|
|
112
|
+
...forcedAddOns,
|
|
113
|
+
])));
|
|
114
|
+
await createApp(createDefaultEnvironment(), {
|
|
115
|
+
projectName: projectName.replace(/^\//, './'),
|
|
116
|
+
targetDir,
|
|
117
|
+
framework,
|
|
118
|
+
typescript: true,
|
|
119
|
+
tailwind: true,
|
|
120
|
+
packageManager: 'pnpm',
|
|
121
|
+
mode: 'file-router',
|
|
122
|
+
chosenAddOns,
|
|
123
|
+
git: true,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
return {
|
|
128
|
+
content: [
|
|
129
|
+
{ type: 'text', text: `Error creating application: ${error}` },
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
content: [{ type: 'text', text: 'Application created successfully' }],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
return {
|
|
139
|
+
content: [
|
|
140
|
+
{ type: 'text', text: `Error creating application: ${error}` },
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
return server;
|
|
146
|
+
}
|
|
147
|
+
export async function runMCPServer(sse, { forcedAddOns, appName, name, }) {
|
|
148
|
+
let transport = null;
|
|
149
|
+
const server = createServer({ appName, forcedAddOns, name });
|
|
150
|
+
if (sse) {
|
|
151
|
+
const app = express();
|
|
152
|
+
app.get('/sse', (req, res) => {
|
|
153
|
+
transport = new SSEServerTransport('/messages', res);
|
|
154
|
+
server.connect(transport);
|
|
155
|
+
});
|
|
156
|
+
app.post('/messages', (req, res) => {
|
|
157
|
+
if (transport) {
|
|
158
|
+
transport.handlePostMessage(req, res);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
const port = process.env.PORT || 8080;
|
|
162
|
+
app.listen(port, () => {
|
|
163
|
+
console.log(`Server is running on port http://localhost:${port}/sse`);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const transport = new StdioServerTransport();
|
|
168
|
+
await server.connect(transport);
|
|
169
|
+
}
|
|
170
|
+
}
|