@restforgejs/mcp-server 1.2.1 → 1.2.3

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.
Files changed (39) hide show
  1. package/dist/server.js +69 -0
  2. package/dist/server.js.map +1 -1
  3. package/dist/tools/codegen/dbschema-apply.js +153 -153
  4. package/dist/tools/codegen/dbschema-diff.js +135 -135
  5. package/dist/tools/codegen/dbschema-template.js +111 -111
  6. package/dist/tools/codegen/index.js +2 -0
  7. package/dist/tools/codegen/index.js.map +1 -1
  8. package/dist/tools/codegen/migrate-payload.d.ts +2 -0
  9. package/dist/tools/codegen/migrate-payload.js +207 -0
  10. package/dist/tools/codegen/migrate-payload.js.map +1 -0
  11. package/dist/tools/designer/generate.d.ts +2 -0
  12. package/dist/tools/designer/generate.js +217 -0
  13. package/dist/tools/designer/generate.js.map +1 -0
  14. package/dist/tools/designer/get-udf-catalog.d.ts +2 -0
  15. package/dist/tools/designer/get-udf-catalog.js +225 -0
  16. package/dist/tools/designer/get-udf-catalog.js.map +1 -0
  17. package/dist/tools/designer/index.d.ts +2 -0
  18. package/dist/tools/designer/index.js +19 -0
  19. package/dist/tools/designer/index.js.map +1 -0
  20. package/dist/tools/designer/init-project.d.ts +2 -0
  21. package/dist/tools/designer/init-project.js +235 -0
  22. package/dist/tools/designer/init-project.js.map +1 -0
  23. package/dist/tools/designer/inspect-plugin.d.ts +2 -0
  24. package/dist/tools/designer/inspect-plugin.js +153 -0
  25. package/dist/tools/designer/inspect-plugin.js.map +1 -0
  26. package/dist/tools/designer/list-plugins.d.ts +2 -0
  27. package/dist/tools/designer/list-plugins.js +141 -0
  28. package/dist/tools/designer/list-plugins.js.map +1 -0
  29. package/dist/tools/designer/preview-files.d.ts +2 -0
  30. package/dist/tools/designer/preview-files.js +155 -0
  31. package/dist/tools/designer/preview-files.js.map +1 -0
  32. package/dist/tools/designer/scaffold-plugin.d.ts +2 -0
  33. package/dist/tools/designer/scaffold-plugin.js +162 -0
  34. package/dist/tools/designer/scaffold-plugin.js.map +1 -0
  35. package/dist/tools/designer/validate-payload.d.ts +2 -0
  36. package/dist/tools/designer/validate-payload.js +163 -0
  37. package/dist/tools/designer/validate-payload.js.map +1 -0
  38. package/dist/tools/runtime/generate-launcher.js +3 -3
  39. package/package.json +1 -1
@@ -0,0 +1,225 @@
1
+ import { z } from 'zod';
2
+ import { resolve } from 'node:path';
3
+ import { execProcess } from '../../lib/exec.js';
4
+ export function registerDesignerGetUdfCatalog(server) {
5
+ server.registerTool('designer_get_udf_catalog', {
6
+ title: 'Get UDF Catalog',
7
+ description: `Get the authoritative JSON catalog of RESTForge Designer UDF structure and rules (valid field types, editor modes, badge colors, id-generation options, navigation item types/depth limits, required appConfig fields, port range, number format, and dashboard widget/chart/data-source options), by running restforge-designer catalog. The catalog is serialized from the designer's own validator constants (single source of truth), so it stays in sync with the installed designer version and never drifts.
8
+
9
+ USE WHEN:
10
+ - Before composing or editing a UDF payload — to ground valid field types and required fields against the designer's own rules
11
+ - The user asks things like "tipe field UDF apa yang valid", "valid UDF field types", "struktur appConfig", "required appConfig fields", "aturan UDF designer", "enum UDF", "what badge colors are allowed", "apa yang boleh di dashboard widget", "which dashboard widgets/charts are available", "show me the UDF catalog"
12
+ - 'designer_validate_payload' rejects a UDF payload and you need the authoritative shape (allowed enum values, required fields) to fix it
13
+ - The user wants the catalog of dashboard widget types, chart engines, or data source methods for a designer UDF
14
+
15
+ DO NOT USE FOR:
16
+ - Validating a concrete UDF payload against a plugin -> use 'designer_validate_payload'
17
+ - Reading the identity/metadata or schema of ONE specific plugin -> use 'designer_inspect_plugin'
18
+ - Listing available designer plugins -> use 'designer_list_plugins'
19
+ - The BACKEND field validation catalog (RDF payload fieldValidation constraints, data types, format presets) -> use 'codegen_get_field_validation_catalog'
20
+
21
+ This tool wraps the RESTForge Designer CLI command: restforge-designer catalog [--section=<fields|navigation|app-config|dashboard|all>], run in the given cwd.
22
+ The catalog is a static constant (it does not depend on cwd) and the command does not modify any file and does not require a license.
23
+
24
+ Preconditions:
25
+ - The 'restforge-designer' binary must be installed and reachable on PATH. This tool pre-checks that by running
26
+ 'restforge-designer --version'; if the binary is missing, the response surfaces that as a non-error precondition.
27
+ - The installed designer must be recent enough to support the 'catalog' command. Older designer builds do not have it; in
28
+ that case the response surfaces a non-error precondition suggesting the designer be updated.
29
+
30
+ Cross-reference (read-before-write):
31
+ - Call this tool BEFORE authoring or editing a UDF payload, and before generating frontend code, to ground the payload shape against the designer's own rules.
32
+
33
+ PRESENTATION GUIDANCE:
34
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
35
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "look up the UDF rules", "validate the payload", "generate the frontend code").
36
+ - Speak in plain language. Summarise the catalog (e.g. how many valid field types, which sections are present); do not paste the entire JSON unless the user explicitly asks for it.
37
+ - When a precondition is not met (binary missing, or too old to support the catalog), frame it as a question or next-step suggestion rather than an error.`,
38
+ inputSchema: {
39
+ cwd: z
40
+ .string()
41
+ .min(1)
42
+ .optional()
43
+ .describe('Working directory where the binary is run. The catalog does not depend on cwd (it is a static constant); defaults to the process cwd when omitted.'),
44
+ section: z
45
+ .enum(['fields', 'navigation', 'app-config', 'dashboard', 'all'])
46
+ .optional()
47
+ .describe('Which slice of the catalog to return. The binary defaults to "all" when omitted (forward-only: not sent unless supplied).'),
48
+ },
49
+ annotations: {
50
+ title: 'Get UDF Catalog',
51
+ readOnlyHint: true,
52
+ idempotentHint: true,
53
+ },
54
+ }, async ({ cwd, section }) => {
55
+ const resolvedCwd = cwd ? resolve(cwd) : process.cwd();
56
+ // Precondition check: the restforge-designer binary must be reachable on PATH.
57
+ // Treated as a non-error precondition per the authoring guide §3.4.
58
+ const probe = await execProcess('restforge-designer', ['--version'], {
59
+ cwd: resolvedCwd,
60
+ timeout: 10_000,
61
+ });
62
+ if (!probe.success) {
63
+ return {
64
+ content: [
65
+ {
66
+ type: 'text',
67
+ text: `Precondition not met: the RESTForge Designer command-line tool is not installed or not on PATH.
68
+
69
+ Working directory: ${resolvedCwd}
70
+ Probe command: ${probe.command}
71
+ Exit code: ${probe.exitCode}
72
+
73
+ For the assistant:
74
+ - The user needs to install RESTForge Designer (and ensure it is on the system PATH) before the UDF catalog can be retrieved.
75
+ - When explaining to the user, say something like "the RESTForge Designer tool isn't installed or isn't on your PATH yet — please install it and try again". Do not mention internal tool names.
76
+ - Once it is installed, retry getting the catalog.`,
77
+ },
78
+ ],
79
+ isError: false, // per §3.4
80
+ };
81
+ }
82
+ // Forward only the arguments the user supplied (forward-only per §3.5 / D6).
83
+ const args = ['catalog'];
84
+ if (section)
85
+ args.push(`--section=${section}`);
86
+ const result = await execProcess('restforge-designer', args, {
87
+ cwd: resolvedCwd,
88
+ timeout: 15_000,
89
+ });
90
+ // Branch 1 — binary too old: the 'catalog' subcommand does not exist yet.
91
+ // Best-effort detection: a failed run whose output carries clap's
92
+ // "unrecognized subcommand" error. Mapped to a NON-error precondition
93
+ // (binary needs updating), per the campaign note and §3.4.
94
+ const combinedOutput = `${result.stderr}\n${result.stdout}`.toLowerCase();
95
+ if (!result.success && combinedOutput.includes('unrecognized subcommand')) {
96
+ return {
97
+ content: [
98
+ {
99
+ type: 'text',
100
+ text: `Precondition not met: the installed RESTForge Designer does not support the UDF catalog yet.
101
+
102
+ Working directory: ${resolvedCwd}
103
+ Installed version: ${probe.stdout.trim() || 'unknown'}
104
+ Command: ${result.command}
105
+ Exit code: ${result.exitCode}
106
+
107
+ For the assistant:
108
+ - The installed RESTForge Designer is too old: it does not recognize the catalog command.
109
+ - When explaining to the user, say something like "your RESTForge Designer is an older version that doesn't expose the UDF catalog yet — please update RESTForge Designer to the latest version and try again". Do not mention internal tool names.
110
+ - Once it is updated, retry getting the catalog.`,
111
+ },
112
+ ],
113
+ isError: false, // non-error precondition: binary needs updating
114
+ };
115
+ }
116
+ // Branch — unexpected crash/timeout: no real exit code (-1). Pre-flight
117
+ // already confirmed the binary spawns, so this is a real failure per §3.4.
118
+ if (result.exitCode === -1) {
119
+ return {
120
+ content: [
121
+ {
122
+ type: 'text',
123
+ text: `Getting the UDF catalog did not complete — the command crashed or timed out.
124
+
125
+ Working directory: ${resolvedCwd}
126
+ Command: ${result.command}
127
+
128
+ --- stderr ---
129
+ ${result.stderr}
130
+ --- end stderr ---
131
+
132
+ For the assistant:
133
+ - The Designer CLI did not finish (likely a crash or timeout), so there is no catalog to report.
134
+ - Tell the user the catalog could not be retrieved and offer to retry. Do not mention internal tool names.`,
135
+ },
136
+ ],
137
+ isError: true, // per §3.4 — unexpected crash/timeout
138
+ };
139
+ }
140
+ // Branch 3 — other non-zero exit: the binary recognizes 'catalog' but failed
141
+ // for another reason. Read-only relay per D7 (isError:false), guide the model
142
+ // to read the output.
143
+ if (!result.success) {
144
+ const stderrBlock = result.stderr
145
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
146
+ : '';
147
+ return {
148
+ content: [
149
+ {
150
+ type: 'text',
151
+ text: `Getting the UDF catalog ran but reported a non-zero exit.
152
+
153
+ Working directory: ${resolvedCwd}
154
+ Command: ${result.command}
155
+ Exit code: ${result.exitCode}
156
+
157
+ --- stdout ---
158
+ ${result.stdout}
159
+ --- end stdout ---
160
+ ${stderrBlock}
161
+ For the assistant:
162
+ - The Designer CLI ran to completion but returned a non-zero exit. Read the output above and relay the situation to the user; this is a verdict to convey, not a tool malfunction.
163
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
164
+ },
165
+ ],
166
+ isError: false, // read-only relay per D7
167
+ };
168
+ }
169
+ // Branch 2 — success: pass the catalog JSON through untouched, with grounding
170
+ // guidance for the assistant. We do not reshape or interpret the catalog.
171
+ let parsed = null;
172
+ let prettyJson = result.stdout;
173
+ let catalogVersion = 'unknown';
174
+ let sectionsLabel = section ?? 'all';
175
+ try {
176
+ parsed = JSON.parse(result.stdout);
177
+ prettyJson = JSON.stringify(parsed, null, 2);
178
+ const root = (parsed ?? {});
179
+ if (typeof root.udfCatalogVersion === 'number' || typeof root.udfCatalogVersion === 'string') {
180
+ catalogVersion = root.udfCatalogVersion;
181
+ }
182
+ // When no --section was supplied, the binary returns the full catalog; surface
183
+ // which top-level sections are present (excluding the version marker).
184
+ if (!section) {
185
+ const keys = Object.keys(root).filter((k) => k !== 'udfCatalogVersion');
186
+ if (keys.length > 0)
187
+ sectionsLabel = keys.join(', ');
188
+ }
189
+ }
190
+ catch {
191
+ // Success exit but unparseable output: relay raw stdout rather than hard-fail
192
+ // (read-only designer tool, D7). The fenced block below carries the raw text.
193
+ }
194
+ return {
195
+ content: [
196
+ {
197
+ type: 'text',
198
+ text: `UDF catalog retrieved successfully.
199
+
200
+ Working directory: ${resolvedCwd}
201
+ Source: restforge-designer (serialized from validator constants) — single source of truth for the installed designer version
202
+ Installed version: ${probe.stdout.trim() || 'unknown'}
203
+ udfCatalogVersion: ${catalogVersion}
204
+ Section(s): ${sectionsLabel}
205
+
206
+ --- UDF Catalog (JSON) ---
207
+ ${prettyJson}
208
+ --- end UDF Catalog (JSON) ---
209
+
210
+ For the assistant:
211
+ - Confirm to the user that the catalog is available. Summarise in plain language (e.g. how many valid field types, which sections are present).
212
+ - Do not paste the full JSON block unless the user explicitly asks. If the user only asked to "see the catalog", offer to drill into a specific section (fields, navigation, app-config, dashboard) instead of dumping everything.
213
+ - When authoring or editing a UDF payload, use this catalog as ground truth to:
214
+ * Restrict field "type" to the values in fields.validFieldTypes; reject anything else as invalid.
215
+ * Ensure appConfig includes every entry in appConfig.requiredFields, and keep port within appConfig.port range.
216
+ * Restrict editor modes, badge colors, id-generation modes/formats, navigation item types, and navigation depth to the enums and limits in the catalog.
217
+ * Restrict dashboard widget types, chart engines, and data source methods to the dashboard section's enums, and respect widgetsRequiringFields / forbiddenFields.
218
+ - This is the DESIGNER (frontend UDF) catalog. Do not confuse it with the backend field validation catalog used for RDF payload fieldValidation constraints.
219
+ - Do not mention internal tool names. Match the user's language.`,
220
+ },
221
+ ],
222
+ };
223
+ });
224
+ }
225
+ //# sourceMappingURL=get-udf-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-udf-catalog.js","sourceRoot":"","sources":["../../../src/tools/designer/get-udf-catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDesignerTools(server: McpServer): void;
@@ -0,0 +1,19 @@
1
+ import { registerDesignerValidatePayload } from './validate-payload.js';
2
+ import { registerDesignerPreviewFiles } from './preview-files.js';
3
+ import { registerDesignerListPlugins } from './list-plugins.js';
4
+ import { registerDesignerInspectPlugin } from './inspect-plugin.js';
5
+ import { registerDesignerScaffoldPlugin } from './scaffold-plugin.js';
6
+ import { registerDesignerInitProject } from './init-project.js';
7
+ import { registerDesignerGenerate } from './generate.js';
8
+ import { registerDesignerGetUdfCatalog } from './get-udf-catalog.js';
9
+ export function registerDesignerTools(server) {
10
+ registerDesignerValidatePayload(server);
11
+ registerDesignerPreviewFiles(server);
12
+ registerDesignerListPlugins(server);
13
+ registerDesignerInspectPlugin(server);
14
+ registerDesignerScaffoldPlugin(server);
15
+ registerDesignerInitProject(server);
16
+ registerDesignerGenerate(server);
17
+ registerDesignerGetUdfCatalog(server);
18
+ }
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/designer/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAErE,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACxC,4BAA4B,CAAC,MAAM,CAAC,CAAC;IACrC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACvC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,6BAA6B,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDesignerInitProject(server: McpServer): void;
@@ -0,0 +1,235 @@
1
+ import { z } from 'zod';
2
+ import { resolve } from 'node:path';
3
+ import { execProcess } from '../../lib/exec.js';
4
+ export function registerDesignerInitProject(server) {
5
+ server.registerTool('designer_init_project', {
6
+ title: 'Init Designer Project',
7
+ description: `Initialise a new frontend project from an existing RESTForge Designer plugin, by running restforge-designer init. This WRITES a new project scaffold (config + structure) to disk, ready for generating frontend code.
8
+
9
+ USE WHEN:
10
+ - The user asks to start/initialise a new frontend project based on a designer plugin
11
+ - The user asks things like "init project frontend baru", "scaffold aplikasi dari plugin designer", "mulai project frontend dengan plugin X", "init a new frontend project", "set up a designer project from plugin <id>", "buat project frontend dari plugin"
12
+ - The user has a plugin id in mind and wants the project skeleton (app config, auth settings, ports) created from it
13
+
14
+ DO NOT USE FOR:
15
+ - Generating frontend code from an existing UDF payload -> use 'designer_generate'
16
+ - Creating a brand new custom plugin from a template -> use 'designer_scaffold_plugin'
17
+ - Listing or inspecting available plugins -> use 'designer_list_plugins' / 'designer_inspect_plugin'
18
+
19
+ This tool wraps the RESTForge Designer CLI command: restforge-designer init --plugin=<plugin> --output=<output> [optional flags], run in the given cwd.
20
+ The --plugin and --output flags are always sent so the binary never drops into interactive prompt mode. Optional flags (app name/code, API URLs, auth settings, port, idle timeout, no-auth, overwrite, plugins dir, license) are forwarded only when supplied.
21
+ This operation is license-gated: the RESTForge Designer license must be active for init to succeed.
22
+
23
+ Preconditions:
24
+ - The 'restforge-designer' binary must be installed and reachable on PATH. This tool pre-checks that by running
25
+ 'restforge-designer --version'; if the binary is missing, the response will surface that as a non-error precondition.
26
+ - A valid, active RESTForge Designer license is required (the operation is license-gated).
27
+
28
+ PRESENTATION GUIDANCE:
29
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
30
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "initialise the frontend project", "generate the frontend code", "scaffold a new plugin").
31
+ - Speak in plain language. Confirm what was created and where; do not paste raw CLI output unless the user explicitly asks.
32
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
33
+ inputSchema: {
34
+ cwd: z
35
+ .string()
36
+ .min(1)
37
+ .describe('Absolute path of the working directory where the binary is run'),
38
+ plugin: z
39
+ .string()
40
+ .min(1)
41
+ .describe('The plugin id to initialise the project from (e.g. vanilla-js-basic). Required.'),
42
+ output: z
43
+ .string()
44
+ .min(1)
45
+ .describe('Path to the output folder where the project will be created (relative to cwd or absolute). Required.'),
46
+ appName: z
47
+ .string()
48
+ .min(1)
49
+ .optional()
50
+ .describe('Human-readable application name for the project.'),
51
+ appCode: z
52
+ .string()
53
+ .min(1)
54
+ .optional()
55
+ .describe('Short application code/identifier for the project.'),
56
+ apiBaseUrl: z
57
+ .string()
58
+ .min(1)
59
+ .optional()
60
+ .describe('Base URL of the backend API the frontend will call.'),
61
+ authAppCode: z
62
+ .string()
63
+ .min(1)
64
+ .optional()
65
+ .describe('Application code used for authentication.'),
66
+ authApiUrl: z
67
+ .string()
68
+ .min(1)
69
+ .optional()
70
+ .describe('Base URL of the authentication API.'),
71
+ port: z
72
+ .number()
73
+ .int()
74
+ .min(1024)
75
+ .max(65535)
76
+ .optional()
77
+ .describe('Dev server port for the project (1024-65535).'),
78
+ idleTimeout: z
79
+ .number()
80
+ .int()
81
+ .min(1)
82
+ .optional()
83
+ .describe('Idle timeout in seconds for the project.'),
84
+ noAuth: z
85
+ .boolean()
86
+ .optional()
87
+ .describe('When true, initialise the project without authentication.'),
88
+ overwrite: z
89
+ .boolean()
90
+ .optional()
91
+ .describe('When true, overwrite the output directory if it already exists.'),
92
+ pluginsDir: z
93
+ .string()
94
+ .min(1)
95
+ .optional()
96
+ .describe('Override path to the plugins folder. When omitted, the binary auto-detects the plugins directory.'),
97
+ license: z
98
+ .string()
99
+ .min(1)
100
+ .optional()
101
+ .describe('License key override for this license-gated operation. When omitted, the binary uses the activated license.'),
102
+ },
103
+ annotations: {
104
+ title: 'Init Designer Project',
105
+ destructiveHint: false, // creates a new project; overwrites only when overwrite=true is supplied
106
+ idempotentHint: false, // each call attempts to create/initialise a project
107
+ },
108
+ }, async ({ cwd, plugin, output, appName, appCode, apiBaseUrl, authAppCode, authApiUrl, port, idleTimeout, noAuth, overwrite, pluginsDir, license, }) => {
109
+ const projectCwd = resolve(cwd);
110
+ // Precondition check: the restforge-designer binary must be reachable on PATH.
111
+ // Treated as a non-error precondition per the authoring guide §3.4.
112
+ const probe = await execProcess('restforge-designer', ['--version'], {
113
+ cwd: projectCwd,
114
+ timeout: 10_000,
115
+ });
116
+ if (!probe.success) {
117
+ return {
118
+ content: [
119
+ {
120
+ type: 'text',
121
+ text: `Precondition not met: the RESTForge Designer command-line tool is not installed or not on PATH.
122
+
123
+ Working directory: ${projectCwd}
124
+ Plugin: ${plugin}
125
+ Output: ${output}
126
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
127
+ Probe command: ${probe.command}
128
+ Exit code: ${probe.exitCode}
129
+
130
+ For the assistant:
131
+ - The user needs to install RESTForge Designer (and ensure it is on the system PATH) before a project can be initialised.
132
+ - When explaining to the user, say something like "the RESTForge Designer tool isn't installed or isn't on your PATH yet — please install it and try again". Do not mention internal tool names.
133
+ - Once it is installed, retry initialising the project.`,
134
+ },
135
+ ],
136
+ isError: false, // per §3.4
137
+ };
138
+ }
139
+ // Always send the required flags (--plugin, --output) so the binary never drops
140
+ // into interactive prompt mode. Forward optional flags only when supplied. per §3.5 / D6
141
+ const args = ['init', `--plugin=${plugin}`, `--output=${output}`];
142
+ if (appName)
143
+ args.push(`--app-name=${appName}`);
144
+ if (appCode)
145
+ args.push(`--app-code=${appCode}`);
146
+ if (apiBaseUrl)
147
+ args.push(`--api-base-url=${apiBaseUrl}`);
148
+ if (authAppCode)
149
+ args.push(`--auth-app-code=${authAppCode}`);
150
+ if (authApiUrl)
151
+ args.push(`--auth-api-url=${authApiUrl}`);
152
+ if (port !== undefined)
153
+ args.push(`--port=${port}`);
154
+ if (idleTimeout !== undefined)
155
+ args.push(`--idle-timeout=${idleTimeout}`);
156
+ if (noAuth)
157
+ args.push('--no-auth');
158
+ if (overwrite)
159
+ args.push('--overwrite');
160
+ if (pluginsDir)
161
+ args.push(`--plugins-dir=${pluginsDir}`);
162
+ if (license)
163
+ args.push(`--license=${license}`);
164
+ const result = await execProcess('restforge-designer', args, {
165
+ cwd: projectCwd,
166
+ timeout: 60_000,
167
+ });
168
+ // D9: write tool. A non-zero exit (incl. -1 crash/timeout) means the init did not
169
+ // complete cleanly — the project may be missing or partial, so the model needs to
170
+ // recover -> isError: true.
171
+ if (result.exitCode !== 0) {
172
+ const stderrBlock = result.stderr
173
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
174
+ : '';
175
+ return {
176
+ content: [
177
+ {
178
+ type: 'text',
179
+ text: `Initialising the Designer project did not complete.
180
+
181
+ Working directory: ${projectCwd}
182
+ Plugin: ${plugin}
183
+ Output: ${output}
184
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
185
+ Command: ${result.command}
186
+ Exit code: ${result.exitCode}
187
+
188
+ --- stdout ---
189
+ ${result.stdout}
190
+ --- end stdout ---
191
+ ${stderrBlock}
192
+ For the assistant:
193
+ - The init did not finish successfully, so the project may not exist or may be partial. Read the CLI output above and explain the most likely cause to the user in plain language. Common causes:
194
+ * The RESTForge Designer license is not active — this operation is license-gated. Suggest the user activate their RESTForge Designer license through the Designer desktop application or its own CLI, then retry. Do not name any internal tool.
195
+ * The output directory already exists and overwrite was not enabled — suggest retrying with overwrite, or choosing a different output path.
196
+ * The plugin id does not exist — suggest listing the available plugins to pick a valid id.
197
+ * The chosen plugin does not support init — soft note: not every plugin supports the 'init' feature. If the CLI says something like "does not support the init feature", suggest picking a plugin that does (the available plugins can be listed to find one). Do not hardcode or assert a permanent list of which plugins support init — treat it as something to confirm from the current plugin list rather than a fixed claim.
198
+ * Exit code -1 — the command crashed or timed out; offer to retry.
199
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
200
+ },
201
+ ],
202
+ isError: true, // per §3.4 / D9 — write did not complete
203
+ };
204
+ }
205
+ // D9: success — exit 0. Labeled facts + fenced raw output per §3.5.
206
+ const stderrBlock = result.stderr
207
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
208
+ : '';
209
+ return {
210
+ content: [
211
+ {
212
+ type: 'text',
213
+ text: `Designer project initialised successfully.
214
+
215
+ Working directory: ${projectCwd}
216
+ Plugin: ${plugin}
217
+ Output: ${output}
218
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
219
+ Command: ${result.command}
220
+ Exit code: ${result.exitCode}
221
+
222
+ --- stdout ---
223
+ ${result.stdout}
224
+ --- end stdout ---
225
+ ${stderrBlock}
226
+ For the assistant:
227
+ - Confirm to the user that the frontend project was initialised. Mention the plugin and the output location in plain language.
228
+ - Suggest the next step: author or supply a UDF payload and then generate the frontend code into the project. The usual flow is validate the payload, preview the files, then generate.
229
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
230
+ },
231
+ ],
232
+ };
233
+ });
234
+ }
235
+ //# sourceMappingURL=init-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-project.js","sourceRoot":"","sources":["../../../src/tools/designer/init-project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDesignerInspectPlugin(server: McpServer): void;