@restforgejs/mcp-server 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/server.js +45 -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/designer/generate.d.ts +2 -0
  7. package/dist/tools/designer/generate.js +212 -0
  8. package/dist/tools/designer/generate.js.map +1 -0
  9. package/dist/tools/designer/index.d.ts +2 -0
  10. package/dist/tools/designer/index.js +17 -0
  11. package/dist/tools/designer/index.js.map +1 -0
  12. package/dist/tools/designer/init-project.d.ts +2 -0
  13. package/dist/tools/designer/init-project.js +235 -0
  14. package/dist/tools/designer/init-project.js.map +1 -0
  15. package/dist/tools/designer/inspect-plugin.d.ts +2 -0
  16. package/dist/tools/designer/inspect-plugin.js +148 -0
  17. package/dist/tools/designer/inspect-plugin.js.map +1 -0
  18. package/dist/tools/designer/list-plugins.d.ts +2 -0
  19. package/dist/tools/designer/list-plugins.js +141 -0
  20. package/dist/tools/designer/list-plugins.js.map +1 -0
  21. package/dist/tools/designer/preview-files.d.ts +2 -0
  22. package/dist/tools/designer/preview-files.js +150 -0
  23. package/dist/tools/designer/preview-files.js.map +1 -0
  24. package/dist/tools/designer/scaffold-plugin.d.ts +2 -0
  25. package/dist/tools/designer/scaffold-plugin.js +162 -0
  26. package/dist/tools/designer/scaffold-plugin.js.map +1 -0
  27. package/dist/tools/designer/validate-payload.d.ts +2 -0
  28. package/dist/tools/designer/validate-payload.js +158 -0
  29. package/dist/tools/designer/validate-payload.js.map +1 -0
  30. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDesignerListPlugins(server: McpServer): void;
@@ -0,0 +1,141 @@
1
+ import { z } from 'zod';
2
+ import { resolve } from 'node:path';
3
+ import { execProcess } from '../../lib/exec.js';
4
+ export function registerDesignerListPlugins(server) {
5
+ server.registerTool('designer_list_plugins', {
6
+ title: 'List Designer Plugins',
7
+ description: `List the RESTForge Designer frontend plugins available in the current environment, by running restforge-designer plugins list. Each plugin defines a frontend tech stack / template the designer can generate against.
8
+
9
+ USE WHEN:
10
+ - The user asks which designer plugins are available, or wants the catalog of frontend templates
11
+ - The user asks things like "plugin apa yang tersedia", "daftar plugin designer", "list frontend plugins", "what designer plugins do I have", "tampilkan plugin frontend", "which frontend templates can I use"
12
+ - Before initialising a project or generating frontend code, to choose which plugin to target
13
+ - The user mentions designer plugins generically and wants an overview
14
+
15
+ DO NOT USE FOR:
16
+ - Inspecting the metadata, schema, or fields of ONE specific plugin -> use 'designer_inspect_plugin'
17
+ - Validating a UDF payload against a plugin -> use 'designer_validate_payload'
18
+ - Previewing the files a payload would generate -> use 'designer_preview_files'
19
+
20
+ This tool wraps the RESTForge Designer CLI command: restforge-designer plugins list [--plugins-dir=<pluginsDir>], run in the given cwd.
21
+ The CLI prints a table of available plugins (auto-detected, or from --plugins-dir when supplied). It does not modify any file and does not require a license.
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
+
27
+ PRESENTATION GUIDANCE:
28
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
29
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "list the available plugins", "inspect a plugin", "generate the frontend code").
30
+ - Speak in plain language. Summarise the plugins (names, count); do not paste raw CLI output unless the user explicitly asks.
31
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
32
+ inputSchema: {
33
+ cwd: z
34
+ .string()
35
+ .min(1)
36
+ .describe('Absolute path of the working directory where the binary is run'),
37
+ pluginsDir: z
38
+ .string()
39
+ .min(1)
40
+ .optional()
41
+ .describe('Override path to the plugins folder. When omitted, the binary auto-detects the plugins directory.'),
42
+ },
43
+ annotations: {
44
+ title: 'List Designer Plugins',
45
+ readOnlyHint: true,
46
+ idempotentHint: true,
47
+ },
48
+ }, async ({ cwd, pluginsDir }) => {
49
+ const projectCwd = resolve(cwd);
50
+ // Precondition check: the restforge-designer binary must be reachable on PATH.
51
+ // Treated as a non-error precondition per the authoring guide §3.4.
52
+ const probe = await execProcess('restforge-designer', ['--version'], {
53
+ cwd: projectCwd,
54
+ timeout: 10_000,
55
+ });
56
+ if (!probe.success) {
57
+ return {
58
+ content: [
59
+ {
60
+ type: 'text',
61
+ text: `Precondition not met: the RESTForge Designer command-line tool is not installed or not on PATH.
62
+
63
+ Working directory: ${projectCwd}
64
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
65
+ Probe command: ${probe.command}
66
+ Exit code: ${probe.exitCode}
67
+
68
+ For the assistant:
69
+ - The user needs to install RESTForge Designer (and ensure it is on the system PATH) before the available plugins can be listed.
70
+ - 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.
71
+ - Once it is installed, retry listing the plugins.`,
72
+ },
73
+ ],
74
+ isError: false, // per §3.4
75
+ };
76
+ }
77
+ // Forward only the arguments the user supplied. per §3.5 / D6
78
+ const args = ['plugins', 'list'];
79
+ if (pluginsDir)
80
+ args.push(`--plugins-dir=${pluginsDir}`);
81
+ const result = await execProcess('restforge-designer', args, {
82
+ cwd: projectCwd,
83
+ timeout: 15_000,
84
+ });
85
+ // D7: read-only tool. Pre-flight confirmed the binary spawns, so only an
86
+ // unexpected crash/timeout (no real exit code -> -1) is a real error.
87
+ if (result.exitCode === -1) {
88
+ return {
89
+ content: [
90
+ {
91
+ type: 'text',
92
+ text: `Listing Designer plugins did not complete — the command crashed or timed out.
93
+
94
+ Working directory: ${projectCwd}
95
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
96
+ Command: ${result.command}
97
+
98
+ --- stderr ---
99
+ ${result.stderr}
100
+ --- end stderr ---
101
+
102
+ For the assistant:
103
+ - The Designer CLI did not finish (likely a crash or timeout), so there is no plugin list to report.
104
+ - Tell the user the list could not be retrieved and offer to retry. Do not mention internal tool names.`,
105
+ },
106
+ ],
107
+ isError: true, // per §3.4 — unexpected crash/timeout
108
+ };
109
+ }
110
+ // D7: single response for ANY real exit code. A non-zero exit is an actionable
111
+ // negative verdict (e.g. plugins directory not found) to relay, not a failure.
112
+ const stderrBlock = result.stderr
113
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
114
+ : '';
115
+ return {
116
+ content: [
117
+ {
118
+ type: 'text',
119
+ text: `Listing Designer plugins ran.
120
+
121
+ Working directory: ${projectCwd}
122
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
123
+ Command: ${result.command}
124
+ Exit code: ${result.exitCode}
125
+
126
+ --- stdout ---
127
+ ${result.stdout}
128
+ --- end stdout ---
129
+ ${stderrBlock}
130
+ For the assistant:
131
+ - The Designer CLI ran to completion. Read the CLI output above and classify the result:
132
+ (a) Positive result — the output is a table of available plugins. Summarise the plugins in plain language (names and how many) and, if the user is choosing one, suggest inspecting a specific plugin for its details.
133
+ (b) Actionable negative verdict — no plugins were found, or the plugins directory override could not be resolved. These are legitimate results to RELAY to the user, not tool malfunctions. Explain the situation (e.g. the plugins folder is empty or the override path is wrong) and offer next steps.
134
+ - A non-zero exit code here means the CLI reported a negative verdict (case b), NOT that the tool failed. Never tell the user "the tool failed" for case (b).
135
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
136
+ },
137
+ ],
138
+ };
139
+ });
140
+ }
141
+ //# sourceMappingURL=list-plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-plugins.js","sourceRoot":"","sources":["../../../src/tools/designer/list-plugins.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 registerDesignerPreviewFiles(server: McpServer): void;
@@ -0,0 +1,150 @@
1
+ import { z } from 'zod';
2
+ import { resolve } from 'node:path';
3
+ import { execProcess } from '../../lib/exec.js';
4
+ export function registerDesignerPreviewFiles(server) {
5
+ server.registerTool('designer_preview_files', {
6
+ title: 'Preview Designer Files',
7
+ description: `Preview (dry-run) the frontend files that the RESTForge Designer would generate from a UI Definition File (UDF) payload, by running restforge-designer preview. This lists what would be produced WITHOUT writing anything to disk.
8
+
9
+ USE WHEN:
10
+ - The user asks which files would be generated, or wants a dry-run before generating frontend code
11
+ - The user asks things like "file apa yang akan di-generate", "preview output frontend designer", "dry-run generate", "what files will the designer produce", "tunjukkan hasil generate tanpa menulis file", "preview the designer output"
12
+ - Before actually generating the frontend code, to inspect the planned output and confirm it looks right
13
+ - The user mentions a designer/frontend UDF payload and wants to see the resulting file layout first
14
+
15
+ DO NOT USE FOR:
16
+ - Validating that a UDF payload is structurally correct against the plugin schema -> use 'designer_validate_payload'
17
+ - Actually generating and writing the frontend files (preview is read-only; the real generation tool writes files)
18
+ - Listing the available designer plugins -> use 'designer_list_plugins'
19
+ - Inspecting one plugin's metadata -> use 'designer_inspect_plugin'
20
+
21
+ This tool wraps the RESTForge Designer CLI command: restforge-designer preview --payload=<payload> [--plugins-dir=<pluginsDir>], run in the given cwd.
22
+ The CLI reads the UDF payload JSON, resolves the target plugin (auto-detected or from --plugins-dir), and prints the list of files it would generate. It 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 will surface that as a non-error precondition.
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. "preview the generated files", "validate the UI definition", "generate the frontend code").
31
+ - Speak in plain language. Summarise the planned file list; 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
+ payload: z
39
+ .string()
40
+ .min(1)
41
+ .describe('Path to the UDF payload JSON file (relative to cwd or absolute)'),
42
+ pluginsDir: z
43
+ .string()
44
+ .min(1)
45
+ .optional()
46
+ .describe('Override path to the plugins folder. When omitted, the binary auto-detects the plugins directory.'),
47
+ },
48
+ annotations: {
49
+ title: 'Preview Designer Files',
50
+ readOnlyHint: true,
51
+ idempotentHint: true,
52
+ },
53
+ }, async ({ cwd, payload, pluginsDir }) => {
54
+ const projectCwd = resolve(cwd);
55
+ // Precondition check: the restforge-designer binary must be reachable on PATH.
56
+ // Treated as a non-error precondition per the authoring guide §3.4.
57
+ const probe = await execProcess('restforge-designer', ['--version'], {
58
+ cwd: projectCwd,
59
+ timeout: 10_000,
60
+ });
61
+ if (!probe.success) {
62
+ return {
63
+ content: [
64
+ {
65
+ type: 'text',
66
+ text: `Precondition not met: the RESTForge Designer command-line tool is not installed or not on PATH.
67
+
68
+ Working directory: ${projectCwd}
69
+ Payload: ${payload}
70
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
71
+ Probe command: ${probe.command}
72
+ Exit code: ${probe.exitCode}
73
+
74
+ For the assistant:
75
+ - The user needs to install RESTForge Designer (and ensure it is on the system PATH) before the generated files can be previewed.
76
+ - 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.
77
+ - Once it is installed, retry the preview.`,
78
+ },
79
+ ],
80
+ isError: false, // per §3.4
81
+ };
82
+ }
83
+ // Forward only the arguments the user supplied. per §3.5 / D6
84
+ const args = ['preview', `--payload=${payload}`];
85
+ if (pluginsDir)
86
+ args.push(`--plugins-dir=${pluginsDir}`);
87
+ const result = await execProcess('restforge-designer', args, {
88
+ cwd: projectCwd,
89
+ timeout: 30_000,
90
+ });
91
+ // D7: read-only tool. Pre-flight confirmed the binary spawns, so only an
92
+ // unexpected crash/timeout (no real exit code -> -1) is a real error.
93
+ if (result.exitCode === -1) {
94
+ return {
95
+ content: [
96
+ {
97
+ type: 'text',
98
+ text: `Designer preview did not complete — the command crashed or timed out.
99
+
100
+ Working directory: ${projectCwd}
101
+ Payload: ${payload}
102
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
103
+ Command: ${result.command}
104
+
105
+ --- stderr ---
106
+ ${result.stderr}
107
+ --- end stderr ---
108
+
109
+ For the assistant:
110
+ - The Designer CLI did not finish (likely a crash or timeout), so there is no preview to report.
111
+ - Tell the user the preview could not be completed and offer to retry. Do not mention internal tool names.`,
112
+ },
113
+ ],
114
+ isError: true, // per §3.4 — unexpected crash/timeout
115
+ };
116
+ }
117
+ // D7: single response for ANY real exit code. A non-zero exit is an actionable
118
+ // negative verdict (invalid payload, plugin/file not found) to relay, not a failure.
119
+ const stderrBlock = result.stderr
120
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
121
+ : '';
122
+ return {
123
+ content: [
124
+ {
125
+ type: 'text',
126
+ text: `Designer preview ran.
127
+
128
+ Working directory: ${projectCwd}
129
+ Payload: ${payload}
130
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
131
+ Command: ${result.command}
132
+ Exit code: ${result.exitCode}
133
+
134
+ --- stdout ---
135
+ ${result.stdout}
136
+ --- end stdout ---
137
+ ${stderrBlock}
138
+ For the assistant:
139
+ - The Designer CLI ran to completion. Read the CLI output above and classify the result:
140
+ (a) Positive result — the output lists the files that would be generated. Summarise the planned files in plain language (how many, what kinds) and offer the next step: generate the frontend code for real.
141
+ (b) Actionable negative verdict — the payload is invalid, the payload file was not found, or the target plugin / plugins directory could not be resolved. These are legitimate results to RELAY to the user, not tool malfunctions. Summarise the concrete problem (which path or field is wrong) and offer to retry after the user fixes it; validating the payload first can help pinpoint structural errors.
142
+ - A non-zero exit code here means the CLI reported a negative verdict (case b), NOT that the tool failed. Never tell the user "the tool failed" for case (b).
143
+ - Soft note: if preview fails with an appConfig/plugin error (e.g. the plugin or app config "not found") while the SAME payload passes validation, the payload may rely on 'extends' / 'include' references that preview does not appear to merge the way validation does. As a possible workaround, suggest pointing the preview at a self-contained payload (inline appConfig and pages) or an already-merged file. This is a tentative hint, not a guaranteed rule — do not state it as certain or tie it to a specific version.
144
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
145
+ },
146
+ ],
147
+ };
148
+ });
149
+ }
150
+ //# sourceMappingURL=preview-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-files.js","sourceRoot":"","sources":["../../../src/tools/designer/preview-files.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 registerDesignerScaffoldPlugin(server: McpServer): void;
@@ -0,0 +1,162 @@
1
+ import { z } from 'zod';
2
+ import { resolve } from 'node:path';
3
+ import { execProcess } from '../../lib/exec.js';
4
+ export function registerDesignerScaffoldPlugin(server) {
5
+ server.registerTool('designer_scaffold_plugin', {
6
+ title: 'Scaffold Designer Plugin',
7
+ description: `Scaffold a new custom RESTForge Designer frontend plugin from a template, by running restforge-designer plugins scaffold. This WRITES a new plugin folder to disk that the user can then customise.
8
+
9
+ USE WHEN:
10
+ - The user asks to create a new custom designer/frontend plugin from scratch
11
+ - The user asks things like "buat plugin custom baru", "scaffold folder plugin designer", "mulai plugin frontend dari template", "create a new designer plugin", "scaffold a frontend plugin", "bikin plugin frontend baru"
12
+ - The user wants a starter plugin folder they can edit to build their own frontend generator template
13
+ - The user names a new plugin id and wants the folder structure generated for it
14
+
15
+ DO NOT USE FOR:
16
+ - Generating a frontend application from a UDF payload -> use 'designer_generate'
17
+ - Initialising a project from an existing plugin -> use 'designer_init_project'
18
+ - Listing the available plugins -> use 'designer_list_plugins'
19
+ - Inspecting one existing plugin's metadata -> use 'designer_inspect_plugin'
20
+
21
+ This tool wraps the RESTForge Designer CLI command: restforge-designer plugins scaffold --id=<id> --output=<output> [--plugins-dir=<pluginsDir>], run in the given cwd.
22
+ The CLI creates a new plugin folder named after the given id under the output directory. It does NOT require a license (scaffolding is license-free).
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 will surface that as a non-error precondition.
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. "scaffold a new plugin", "list the available plugins", "generate the frontend code").
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
+ id: z
39
+ .string()
40
+ .min(1)
41
+ .describe('The id of the new plugin to scaffold (e.g. my-custom-plugin)'),
42
+ output: z
43
+ .string()
44
+ .min(1)
45
+ .describe('Path to the output folder where the new plugin will be created (relative to cwd or absolute)'),
46
+ pluginsDir: z
47
+ .string()
48
+ .min(1)
49
+ .optional()
50
+ .describe('Override path to the plugins folder. When omitted, the binary auto-detects the plugins directory.'),
51
+ },
52
+ annotations: {
53
+ title: 'Scaffold Designer Plugin',
54
+ destructiveHint: false, // creates a new plugin folder; does not delete or overwrite existing data
55
+ idempotentHint: false, // each call attempts to create a new plugin folder
56
+ },
57
+ }, async ({ cwd, id, output, pluginsDir }) => {
58
+ const projectCwd = resolve(cwd);
59
+ // Precondition check: the restforge-designer binary must be reachable on PATH.
60
+ // Treated as a non-error precondition per the authoring guide §3.4.
61
+ const probe = await execProcess('restforge-designer', ['--version'], {
62
+ cwd: projectCwd,
63
+ timeout: 10_000,
64
+ });
65
+ if (!probe.success) {
66
+ return {
67
+ content: [
68
+ {
69
+ type: 'text',
70
+ text: `Precondition not met: the RESTForge Designer command-line tool is not installed or not on PATH.
71
+
72
+ Working directory: ${projectCwd}
73
+ Plugin id: ${id}
74
+ Output: ${output}
75
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
76
+ Probe command: ${probe.command}
77
+ Exit code: ${probe.exitCode}
78
+
79
+ For the assistant:
80
+ - The user needs to install RESTForge Designer (and ensure it is on the system PATH) before a plugin can be scaffolded.
81
+ - 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.
82
+ - Once it is installed, retry scaffolding the plugin.`,
83
+ },
84
+ ],
85
+ isError: false, // per §3.4
86
+ };
87
+ }
88
+ // Forward only the arguments the user supplied. Required flags are always sent. per §3.5 / D6
89
+ const args = ['plugins', 'scaffold', `--id=${id}`, `--output=${output}`];
90
+ if (pluginsDir)
91
+ args.push(`--plugins-dir=${pluginsDir}`);
92
+ const result = await execProcess('restforge-designer', args, {
93
+ cwd: projectCwd,
94
+ timeout: 30_000,
95
+ });
96
+ // D9: write tool. A non-zero exit (incl. -1 crash/timeout) means the write did
97
+ // not complete cleanly — the plugin folder may be missing or partial, so the
98
+ // model needs to recover -> isError: true.
99
+ if (result.exitCode !== 0) {
100
+ const stderrBlock = result.stderr
101
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
102
+ : '';
103
+ return {
104
+ content: [
105
+ {
106
+ type: 'text',
107
+ text: `Scaffolding the Designer plugin did not complete.
108
+
109
+ Working directory: ${projectCwd}
110
+ Plugin id: ${id}
111
+ Output: ${output}
112
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
113
+ Command: ${result.command}
114
+ Exit code: ${result.exitCode}
115
+
116
+ --- stdout ---
117
+ ${result.stdout}
118
+ --- end stdout ---
119
+ ${stderrBlock}
120
+ For the assistant:
121
+ - The scaffold did not finish successfully, so the plugin folder 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:
122
+ * The output directory already exists or is not writable — suggest a different output path or clearing the existing folder.
123
+ * The plugin id is invalid (bad characters) — suggest a simpler id.
124
+ * Exit code -1 — the command crashed or timed out; offer to retry.
125
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
126
+ },
127
+ ],
128
+ isError: true, // per §3.4 / D9 — write did not complete
129
+ };
130
+ }
131
+ // D9: success — exit 0. Labeled facts + fenced raw output per §3.5.
132
+ const stderrBlock = result.stderr
133
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
134
+ : '';
135
+ return {
136
+ content: [
137
+ {
138
+ type: 'text',
139
+ text: `Designer plugin scaffolded successfully.
140
+
141
+ Working directory: ${projectCwd}
142
+ Plugin id: ${id}
143
+ Output: ${output}
144
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
145
+ Command: ${result.command}
146
+ Exit code: ${result.exitCode}
147
+
148
+ --- stdout ---
149
+ ${result.stdout}
150
+ --- end stdout ---
151
+ ${stderrBlock}
152
+ For the assistant:
153
+ - Confirm to the user that the new plugin folder was created. Mention the plugin id and the output location in plain language.
154
+ - The scaffold is a starting point: the user will edit the generated plugin files (templates, schema) to build their own frontend generator.
155
+ - Suggest a sensible next step, e.g. inspecting or listing the plugins to confirm the new one is picked up, or authoring a UDF payload that targets it.
156
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
157
+ },
158
+ ],
159
+ };
160
+ });
161
+ }
162
+ //# sourceMappingURL=scaffold-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold-plugin.js","sourceRoot":"","sources":["../../../src/tools/designer/scaffold-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,UAAU,8BAA8B,CAAC,MAAiB;IAC9D,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;uGAyBoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,gEAAgE,CAAC;YAC7E,EAAE,EAAE,CAAC;iBACF,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,8DAA8D,CAAC;YAC3E,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,8FAA8F,CAAC;YAC3G,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CAAC,mGAAmG,CAAC;SACjH;QACD,WAAW,EAAE;YACX,KAAK,EAAE,0BAA0B;YACjC,eAAe,EAAE,KAAK,EAAE,0EAA0E;YAClG,cAAc,EAAE,KAAK,EAAG,mDAAmD;SAC5E;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAEhC,+EAA+E;QAC/E,oEAAoE;QACpE,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,oBAAoB,EAAE,CAAC,WAAW,CAAC,EAAE;YACnE,GAAG,EAAE,UAAU;YACf,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;qBAEC,UAAU;aAClB,EAAE;UACL,MAAM;eACD,UAAU,IAAI,aAAa;iBACzB,KAAK,CAAC,OAAO;aACjB,KAAK,CAAC,QAAQ;;;;;sDAK2B;qBACzC;iBACF;gBACD,OAAO,EAAE,KAAK,EAAE,WAAW;aAC5B,CAAC;QACJ,CAAC;QAED,8FAA8F;QAC9F,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,MAAM,EAAE,CAAC,CAAC;QACzE,IAAI,UAAU;YAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,UAAU,EAAE,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,oBAAoB,EAAE,IAAI,EAAE;YAC3D,GAAG,EAAE,UAAU;YACf,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAEH,+EAA+E;QAC/E,6EAA6E;QAC7E,2CAA2C;QAC3C,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM;gBAC/B,CAAC,CAAC,qBAAqB,MAAM,CAAC,MAAM,wBAAwB;gBAC5D,CAAC,CAAC,EAAE,CAAC;YACP,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;qBAEC,UAAU;aAClB,EAAE;UACL,MAAM;eACD,UAAU,IAAI,aAAa;WAC/B,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;EAG1B,MAAM,CAAC,MAAM;;EAEb,WAAW;;;;;;kIAMqH;qBACrH;iBACF;gBACD,OAAO,EAAE,IAAI,EAAE,yCAAyC;aACzD,CAAC;QACJ,CAAC;QAED,oEAAoE;QACpE,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM;YAC/B,CAAC,CAAC,qBAAqB,MAAM,CAAC,MAAM,wBAAwB;YAC5D,CAAC,CAAC,EAAE,CAAC;QACP,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;qBAEG,UAAU;aAClB,EAAE;UACL,MAAM;eACD,UAAU,IAAI,aAAa;WAC/B,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;EAG1B,MAAM,CAAC,MAAM;;EAEb,WAAW;;;;;kIAKqH;iBACvH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerDesignerValidatePayload(server: McpServer): void;
@@ -0,0 +1,158 @@
1
+ import { z } from 'zod';
2
+ import { resolve } from 'node:path';
3
+ import { execProcess } from '../../lib/exec.js';
4
+ export function registerDesignerValidatePayload(server) {
5
+ server.registerTool('designer_validate_payload', {
6
+ title: 'Validate Designer Payload',
7
+ description: `Validate a frontend UI Definition File (UDF) payload against the schema of the RESTForge Designer plugin it targets, by running restforge-designer validate.
8
+
9
+ USE WHEN:
10
+ - The user asks to validate, check, or verify a frontend designer payload / UI definition (UDF) file
11
+ - The user asks things like "validasi UDF", "cek payload frontend", "is this UI definition valid", "validate designer payload", "apakah payload UDF benar", "check the frontend payload against the plugin schema"
12
+ - Before previewing or generating frontend code from a UDF, to confirm the payload is structurally valid against the plugin schema
13
+ - The user mentions a designer/frontend payload JSON and wants to know whether it conforms to the plugin it targets
14
+ - Routine pre-generation sanity check on a UDF file
15
+
16
+ DO NOT USE FOR:
17
+ - Validating a backend RDF payload against the database schema -> use 'codegen_validate_payload'
18
+ - Validating an SDF (database schema definition) -> use 'codegen_dbschema_validate'
19
+ - Validating raw SQL -> use 'codegen_validate_sql'
20
+ - Generating the frontend code itself (this only validates, it does not write files)
21
+
22
+ This tool wraps the RESTForge Designer CLI command: restforge-designer validate --payload=<payload> [--plugins-dir=<pluginsDir>], run in the given cwd.
23
+ The CLI reads the UDF payload JSON, resolves the target plugin (auto-detected or from --plugins-dir), and reports whether
24
+ the payload is valid against that plugin's schema, listing structural errors when it is not. It does not modify any file and
25
+ does not require a license.
26
+
27
+ Preconditions:
28
+ - The 'restforge-designer' binary must be installed and reachable on PATH. This tool pre-checks that by running
29
+ 'restforge-designer --version'; if the binary is missing, the response will surface that as a non-error precondition.
30
+
31
+ PRESENTATION GUIDANCE:
32
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
33
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "validate the UI definition", "preview the generated files", "generate the frontend code").
34
+ - Speak in plain language. Summarise the result; do not paste raw CLI output unless the user explicitly asks.
35
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
36
+ inputSchema: {
37
+ cwd: z
38
+ .string()
39
+ .min(1)
40
+ .describe('Absolute path of the working directory where the binary is run'),
41
+ payload: z
42
+ .string()
43
+ .min(1)
44
+ .describe('Path to the UDF payload JSON file (relative to cwd or absolute)'),
45
+ pluginsDir: z
46
+ .string()
47
+ .min(1)
48
+ .optional()
49
+ .describe('Override path to the plugins folder. When omitted, the binary auto-detects the plugins directory.'),
50
+ },
51
+ annotations: {
52
+ title: 'Validate Designer Payload',
53
+ readOnlyHint: true,
54
+ idempotentHint: true,
55
+ },
56
+ }, async ({ cwd, payload, pluginsDir }) => {
57
+ const projectCwd = resolve(cwd);
58
+ // Precondition check: the restforge-designer binary must be reachable on PATH.
59
+ // Treated as a non-error precondition per the authoring guide §3.4. The probe
60
+ // distinguishes "binary missing" (precondition) from "binary ran and reported
61
+ // something" (which falls through to the real execution below).
62
+ const probe = await execProcess('restforge-designer', ['--version'], {
63
+ cwd: projectCwd,
64
+ timeout: 10_000,
65
+ });
66
+ if (!probe.success) {
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: `Precondition not met: the RESTForge Designer command-line tool is not installed or not on PATH.
72
+
73
+ Working directory: ${projectCwd}
74
+ Payload: ${payload}
75
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
76
+ Probe command: ${probe.command}
77
+ Exit code: ${probe.exitCode}
78
+
79
+ For the assistant:
80
+ - The user needs to install RESTForge Designer (and ensure it is on the system PATH) before a frontend payload can be validated.
81
+ - 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.
82
+ - Once it is installed, retry validating the payload.`,
83
+ },
84
+ ],
85
+ isError: false, // per §3.4
86
+ };
87
+ }
88
+ // Forward only the arguments the user supplied. The plugins directory is
89
+ // auto-detected by the binary when --plugins-dir is omitted. per §3.5
90
+ const args = ['validate', `--payload=${payload}`];
91
+ if (pluginsDir)
92
+ args.push(`--plugins-dir=${pluginsDir}`);
93
+ const result = await execProcess('restforge-designer', args, {
94
+ cwd: projectCwd,
95
+ timeout: 30_000,
96
+ });
97
+ // D7: this is a read-only tool. The pre-flight already confirmed the binary
98
+ // spawns, so an unexpected crash/timeout (no real exit code -> -1) is the only
99
+ // real error here -> isError: true. Any genuine exit code is a verdict to relay.
100
+ if (result.exitCode === -1) {
101
+ return {
102
+ content: [
103
+ {
104
+ type: 'text',
105
+ text: `Designer payload validation did not complete — the command crashed or timed out.
106
+
107
+ Working directory: ${projectCwd}
108
+ Payload: ${payload}
109
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
110
+ Command: ${result.command}
111
+
112
+ --- stderr ---
113
+ ${result.stderr}
114
+ --- end stderr ---
115
+
116
+ For the assistant:
117
+ - The Designer CLI did not finish (likely a crash or timeout), so there is no validation verdict to report.
118
+ - Tell the user the check could not be completed and offer to retry. Do not mention internal tool names.`,
119
+ },
120
+ ],
121
+ isError: true, // per §3.4 — unexpected crash/timeout
122
+ };
123
+ }
124
+ // D7: single response for ANY real exit code (success branch no longer split on
125
+ // result.success). A non-zero exit means the CLI reported an actionable negative
126
+ // verdict (invalid payload, plugin/file not found), which is a legitimate result
127
+ // to relay — NOT a tool failure. The model classifies from the fenced output.
128
+ const stderrBlock = result.stderr
129
+ ? `\n--- stderr ---\n${result.stderr}\n--- end stderr ---\n`
130
+ : '';
131
+ return {
132
+ content: [
133
+ {
134
+ type: 'text',
135
+ text: `Designer payload validation ran.
136
+
137
+ Working directory: ${projectCwd}
138
+ Payload: ${payload}
139
+ Plugins dir: ${pluginsDir ?? 'auto-detect'}
140
+ Command: ${result.command}
141
+ Exit code: ${result.exitCode}
142
+
143
+ --- stdout ---
144
+ ${result.stdout}
145
+ --- end stdout ---
146
+ ${stderrBlock}
147
+ For the assistant:
148
+ - The Designer CLI ran to completion. Read the CLI output above and classify the result:
149
+ (a) Positive result — the payload is VALID against the target plugin schema. Confirm this in plain language and suggest the next step: preview the files that would be generated from this payload, or generate the frontend code. Describe steps by what they do.
150
+ (b) Actionable negative verdict — the payload is INVALID (the output lists structural errors), or the payload file was not found, or the target plugin / plugins directory could not be resolved. These are legitimate results to RELAY to the user, not tool malfunctions. Summarise the concrete problems (which fields, components, or paths are wrong) and offer to re-check after the user fixes them.
151
+ - A non-zero exit code here means the CLI reported a negative verdict (case b), NOT that the tool failed. Never tell the user "the tool failed" for case (b).
152
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names. Match the user's language.`,
153
+ },
154
+ ],
155
+ };
156
+ });
157
+ }
158
+ //# sourceMappingURL=validate-payload.js.map