@restforgejs/mcp-server 1.2.3 → 1.2.4

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 (62) hide show
  1. package/dist/server.js +52 -7
  2. package/dist/server.js.map +1 -1
  3. package/dist/tools/codegen/create-kafka-consumer.d.ts +2 -0
  4. package/dist/tools/codegen/create-kafka-consumer.js +140 -0
  5. package/dist/tools/codegen/create-kafka-consumer.js.map +1 -0
  6. package/dist/tools/codegen/create-processor.d.ts +2 -0
  7. package/dist/tools/codegen/create-processor.js +157 -0
  8. package/dist/tools/codegen/create-processor.js.map +1 -0
  9. package/dist/tools/codegen/generate-test.d.ts +2 -0
  10. package/dist/tools/codegen/generate-test.js +149 -0
  11. package/dist/tools/codegen/generate-test.js.map +1 -0
  12. package/dist/tools/codegen/index.js +6 -0
  13. package/dist/tools/codegen/index.js.map +1 -1
  14. package/dist/tools/codegen/migrate-payload.js +3 -0
  15. package/dist/tools/codegen/migrate-payload.js.map +1 -1
  16. package/dist/tools/data/index.d.ts +2 -0
  17. package/dist/tools/data/index.js +7 -0
  18. package/dist/tools/data/index.js.map +1 -0
  19. package/dist/tools/data/pull.d.ts +2 -0
  20. package/dist/tools/data/pull.js +202 -0
  21. package/dist/tools/data/pull.js.map +1 -0
  22. package/dist/tools/data/push.d.ts +2 -0
  23. package/dist/tools/data/push.js +190 -0
  24. package/dist/tools/data/push.js.map +1 -0
  25. package/dist/tools/key/generate.d.ts +2 -0
  26. package/dist/tools/key/generate.js +130 -0
  27. package/dist/tools/key/generate.js.map +1 -0
  28. package/dist/tools/key/index.d.ts +2 -0
  29. package/dist/tools/key/index.js +9 -0
  30. package/dist/tools/key/index.js.map +1 -0
  31. package/dist/tools/key/list.d.ts +2 -0
  32. package/dist/tools/key/list.js +126 -0
  33. package/dist/tools/key/list.js.map +1 -0
  34. package/dist/tools/key/revoke.d.ts +2 -0
  35. package/dist/tools/key/revoke.js +117 -0
  36. package/dist/tools/key/revoke.js.map +1 -0
  37. package/dist/tools/project/delete.d.ts +2 -0
  38. package/dist/tools/project/delete.js +116 -0
  39. package/dist/tools/project/delete.js.map +1 -0
  40. package/dist/tools/project/index.d.ts +2 -0
  41. package/dist/tools/project/index.js +7 -0
  42. package/dist/tools/project/index.js.map +1 -0
  43. package/dist/tools/project/list.d.ts +2 -0
  44. package/dist/tools/project/list.js +107 -0
  45. package/dist/tools/project/list.js.map +1 -0
  46. package/dist/tools/setup/clear-default-config.d.ts +2 -0
  47. package/dist/tools/setup/clear-default-config.js +104 -0
  48. package/dist/tools/setup/clear-default-config.js.map +1 -0
  49. package/dist/tools/setup/get-default-config.d.ts +2 -0
  50. package/dist/tools/setup/get-default-config.js +104 -0
  51. package/dist/tools/setup/get-default-config.js.map +1 -0
  52. package/dist/tools/setup/index.js +8 -0
  53. package/dist/tools/setup/index.js.map +1 -1
  54. package/dist/tools/setup/init-config.js +3 -5
  55. package/dist/tools/setup/init-config.js.map +1 -1
  56. package/dist/tools/setup/list-configs.d.ts +2 -0
  57. package/dist/tools/setup/list-configs.js +104 -0
  58. package/dist/tools/setup/list-configs.js.map +1 -0
  59. package/dist/tools/setup/set-default-config.d.ts +2 -0
  60. package/dist/tools/setup/set-default-config.js +109 -0
  61. package/dist/tools/setup/set-default-config.js.map +1 -0
  62. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -6,6 +6,9 @@ import { registerSetupTools } from './tools/setup/index.js';
6
6
  import { registerCodegenTools } from './tools/codegen/index.js';
7
7
  import { registerRuntimeTools } from './tools/runtime/index.js';
8
8
  import { registerDesignerTools } from './tools/designer/index.js';
9
+ import { registerDataTools } from './tools/data/index.js';
10
+ import { registerKeyTools } from './tools/key/index.js';
11
+ import { registerProjectTools } from './tools/project/index.js';
9
12
  const SERVER_NAME = 'restforge-mcp';
10
13
  // Read the version from package.json at runtime so the advertised server version
11
14
  // never drifts from the published package version. createRequire resolves the JSON
@@ -218,8 +221,10 @@ that is NOT covered by an available catalog tool:
218
221
  2. Do NOT guess based on similar frameworks.
219
222
  3. Either:
220
223
  (a) Acknowledge that the specific information is not available via
221
- this MCP server and suggest consulting the canonical docs at
222
- https://restforge.dev/docs.
224
+ this MCP server and suggest consulting the canonical, up-to-date
225
+ RESTForge handbook at https://github.com/restforge/handbook.
226
+ (Do NOT point users to https://restforge.dev/docs — that site is
227
+ outdated; the GitHub handbook is the live source of truth.)
223
228
  (b) Ask the user to clarify if the question can be reframed to
224
229
  match an available catalog tool.
225
230
 
@@ -279,11 +284,19 @@ build or generate a frontend UDF, route along this flow:
279
284
  codegen_migrate_payload -> designer_get_udf_catalog ->
280
285
  designer_validate_payload -> designer_preview_files -> designer_generate
281
286
 
282
- - On-ramp: if the user has a backend RDF but no UDF yet, start with
283
- 'codegen_migrate_payload' it converts an existing backend payload (RDF)
284
- into a split multi-file UDF set (this verb belongs to the backend
285
- 'restforge' CLI, so it lives in the codegen domain even though its output
286
- is a UDF).
287
+ - CREATING a UDF START HERE (firm rule): the FIRST path to produce a UDF
288
+ is ALWAYS 'codegen_migrate_payload'. RESTForge is backend-first; a UDF is
289
+ normally DERIVED from an existing backend payload (RDF), not written by
290
+ hand. 'codegen_migrate_payload' converts an existing RDF into a split
291
+ multi-file UDF set (this verb belongs to the backend 'restforge' CLI, so it
292
+ lives in the codegen domain even though its output is a UDF).
293
+ - Do NOT hand-author a UDF from scratch (writing the JSON yourself) when a
294
+ backend RDF payload exists. Convert it with 'codegen_migrate_payload'
295
+ first, then refine the generated UDF.
296
+ - Author a UDF from scratch (grounded by 'designer_get_udf_catalog') ONLY
297
+ when there is genuinely no backend RDF to migrate from. If unsure whether
298
+ an RDF exists, ask the user or look for the backend 'payload/' directory
299
+ BEFORE hand-authoring.
287
300
  - Grounding: the authoritative structure and rules of a UDF (valid field
288
301
  types, required appConfig fields, enums, limits, dashboard widget/chart/
289
302
  data-source options) come from 'designer_get_udf_catalog', which is
@@ -295,6 +308,35 @@ build or generate a frontend UDF, route along this flow:
295
308
  - Then validate ('designer_validate_payload'), preview
296
309
  ('designer_preview_files'), and finally generate ('designer_generate'),
297
310
  pointing those at the aggregator UDF file, not the page fragments.
311
+
312
+ INTERACTIVE COMMANDS — knowledge only, NOT wrapped as tools:
313
+ Some restforge commands are interactive and are intentionally NOT exposed as
314
+ tools. When the user asks about them, EXPLAIN what they do and give the exact
315
+ command for the user to run themselves in their terminal — this server cannot
316
+ drive the interactive prompts.
317
+
318
+ - 'fast-track' — command: npx restforge fast-track --project=<name> --schema-path=<dir> [--config=<file>] [--license=<KEY>] [--overwrite]
319
+ Purpose: a single interactive flow that scaffolds a full REST API (and
320
+ optionally the frontend app) from an SDF. It does NOT add new generation
321
+ logic; it ORCHESTRATES the existing restforge steps in order: write env (init
322
+ if needed) -> validate --auto-create-db -> config set-default -> schema
323
+ migrate -> payload generate -> payload sync --expand-fk -> endpoint create,
324
+ then (if frontend scope) migrate RDF->UDF -> designer generate, and finally
325
+ writes a server-start launcher.
326
+ Interactive prompts: license + DB params, a scope menu (1 = REST API only,
327
+ 2 = REST API + frontend), and a confirmation. Because of these prompts it
328
+ cannot be invoked by this server.
329
+ How to help the user:
330
+ * When the user wants the FASTEST path from an SDF to a running app, tell them
331
+ to run the command above in their terminal and walk them through the prompts
332
+ (license, database, scope choice, confirm).
333
+ * '--overwrite' is DESTRUCTIVE (drops tables and regenerates) — warn before
334
+ suggesting it.
335
+ * If the user prefers a non-interactive / step-by-step path, the same pipeline
336
+ can be reproduced with the individual tools: schema migrate -> generate
337
+ payload -> sync payload (expand FK) -> create endpoint, then (frontend)
338
+ codegen_migrate_payload -> designer validate/preview/generate. Offer this as
339
+ the automatable alternative to fast-track.
298
340
  `.trim();
299
341
  export async function startServer() {
300
342
  const server = new McpServer({
@@ -308,6 +350,9 @@ export async function startServer() {
308
350
  registerCodegenTools(server);
309
351
  registerRuntimeTools(server);
310
352
  registerDesignerTools(server);
353
+ registerDataTools(server);
354
+ registerKeyTools(server);
355
+ registerProjectTools(server);
311
356
  const transport = new StdioServerTransport();
312
357
  await server.connect(transport);
313
358
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,WAAW,GAAG,eAAe,CAAC;AAEpC,iFAAiF;AACjF,mFAAmF;AACnF,6EAA6E;AAC7E,mFAAmF;AACnF,gFAAgF;AAChF,kFAAkF;AAClF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtF,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwR3B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;KACxB,EACD;QACE,YAAY,EAAE,mBAAmB;KAClC,CACF,CAAC;IAEF,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,WAAW,GAAG,eAAe,CAAC;AAEpC,iFAAiF;AACjF,mFAAmF;AACnF,6EAA6E;AAC7E,mFAAmF;AACnF,gFAAgF;AAChF,kFAAkF;AAClF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtF,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+T3B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;KACxB,EACD;QACE,YAAY,EAAE,mBAAmB;KAClC,CACF,CAAC;IAEF,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerCodegenCreateKafkaConsumer(server: McpServer): void;
@@ -0,0 +1,140 @@
1
+ import { z } from 'zod';
2
+ import { access } from 'node:fs/promises';
3
+ import { resolve, join } from 'node:path';
4
+ import { execProcess } from '../../lib/exec.js';
5
+ export function registerCodegenCreateKafkaConsumer(server) {
6
+ server.registerTool('codegen_create_kafka_consumer', {
7
+ title: 'Create Kafka Consumer',
8
+ description: `Generate Kafka consumer source code from a payload JSON file, by wrapping restforge kafka consumer-create. The output is written under src/consumers/<project>/<name>/ and is later run by the internal 'restforge-consumer' binary.
9
+
10
+ USE WHEN:
11
+ - The user wants to create or scaffold a Kafka consumer from a consumer payload, e.g. "buat kafka consumer", "generate consumer", "create kafka consumer dari payload"
12
+ - The user has a consumer payload JSON and wants the matching consumer code generated into a backend project
13
+ - The user mentions consuming Kafka topics/events and needs the handler scaffolded
14
+
15
+ DO NOT USE FOR:
16
+ - Generating a REST endpoint -> use 'codegen_create_endpoint'
17
+ - Generating a processor / background job -> use 'codegen_create_processor'
18
+ - Deploying or running the consumer -> out of scope (the generated code is run by the internal 'restforge-consumer' binary, not this server)
19
+
20
+ This tool runs: npx restforge kafka consumer-create --project=<project> --name=<name> --payload=<payload> [--force] in the given cwd.
21
+
22
+ Preconditions:
23
+ - The project must have @restforgejs/platform installed in node_modules.
24
+ - The named consumer payload JSON must exist. This tool does not pre-check it — if the CLI fails, the failure response surfaces the cause.
25
+ - Without 'force', the command fails if the consumer files already exist.
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. "generate the Kafka consumer").
30
+ - Speak in plain language; summarise the result. Do not paste raw CLI output unless the user explicitly asks.
31
+ - Mention that the generated consumer is run separately by the internal consumer runtime, not by this assistant.
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 backend project folder (must contain node_modules/@restforgejs/platform)'),
38
+ project: z.string().min(1).describe('Target project name. REQUIRED.'),
39
+ name: z.string().min(1).describe('Consumer name to create. REQUIRED.'),
40
+ payload: z
41
+ .string()
42
+ .min(1)
43
+ .describe('Path or file name of the consumer payload JSON. REQUIRED.'),
44
+ force: z
45
+ .boolean()
46
+ .optional()
47
+ .describe('Overwrite existing consumer files. Without it, the command fails if the files already exist.'),
48
+ },
49
+ annotations: {
50
+ title: 'Create Kafka Consumer',
51
+ readOnlyHint: false,
52
+ idempotentHint: false,
53
+ destructiveHint: false,
54
+ },
55
+ }, async ({ cwd, project, name, payload, force }) => {
56
+ const projectCwd = resolve(cwd);
57
+ try {
58
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
59
+ }
60
+ catch {
61
+ return {
62
+ content: [
63
+ {
64
+ type: 'text',
65
+ text: `Precondition not met: the RESTForge package is not installed in this project.
66
+
67
+ Project path: ${projectCwd}
68
+ Expected location: node_modules/@restforgejs/platform
69
+ Requested consumer: ${name}
70
+ Requested payload: ${payload}
71
+
72
+ For the assistant:
73
+ - The user needs to install the RESTForge package before a Kafka consumer can be generated.
74
+ - Suggest installing the package first, then retry. When explaining, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
75
+ },
76
+ ],
77
+ isError: false,
78
+ };
79
+ }
80
+ const args = ['restforge', 'kafka', 'consumer-create', `--project=${project}`, `--name=${name}`, `--payload=${payload}`];
81
+ if (force)
82
+ args.push('--force');
83
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 60_000 });
84
+ if (!result.success) {
85
+ return {
86
+ content: [
87
+ {
88
+ type: 'text',
89
+ text: `Failed to create the Kafka consumer.
90
+
91
+ Project path: ${projectCwd}
92
+ Project: ${project}
93
+ Consumer: ${name}
94
+ Payload: ${payload}
95
+ Command: ${result.command}
96
+ Exit code: ${result.exitCode}
97
+
98
+ --- CLI output ---
99
+ stdout:
100
+ ${result.stdout}
101
+
102
+ stderr:
103
+ ${result.stderr}
104
+ --- end CLI output ---
105
+
106
+ For the assistant:
107
+ - Tell the user the Kafka consumer was not generated successfully.
108
+ - Summarise the most likely cause from the CLI output in plain language (common causes: the payload file was not found, the payload is invalid, the consumer files already exist without force, or the target project does not exist). Do not paste raw output unless the user asks.
109
+ - Offer to retry once the issue is resolved. Do not mention internal tool names.`,
110
+ },
111
+ ],
112
+ isError: true,
113
+ };
114
+ }
115
+ return {
116
+ content: [
117
+ {
118
+ type: 'text',
119
+ text: `Kafka consumer created.
120
+
121
+ Project path: ${projectCwd}
122
+ Project: ${project}
123
+ Consumer: ${name}
124
+ Payload: ${payload}
125
+ Command: ${result.command}
126
+
127
+ --- CLI output ---
128
+ ${result.stdout}
129
+ --- end CLI output ---
130
+
131
+ For the assistant:
132
+ - Confirm the Kafka consumer source was generated under src/consumers/<project>/<name>/.
133
+ - Mention that the consumer is run separately by the internal consumer runtime (restforge-consumer), not by this assistant.
134
+ - Keep the reply concise. Do not paste raw CLI output unless the user explicitly asks. Do not mention internal tool names.`,
135
+ },
136
+ ],
137
+ };
138
+ });
139
+ }
140
+ //# sourceMappingURL=create-kafka-consumer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-kafka-consumer.js","sourceRoot":"","sources":["../../../src/tools/codegen/create-kafka-consumer.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 registerCodegenCreateProcessor(server: McpServer): void;
@@ -0,0 +1,157 @@
1
+ import { z } from 'zod';
2
+ import { access } from 'node:fs/promises';
3
+ import { resolve, join } from 'node:path';
4
+ import { execProcess } from '../../lib/exec.js';
5
+ export function registerCodegenCreateProcessor(server) {
6
+ server.registerTool('codegen_create_processor', {
7
+ title: 'Create Processor Module',
8
+ description: `Generate a processor (a background job / custom business-logic handler) from a payload JSON file, by wrapping restforge processor create. The processor exposes an endpoint whose router + metadata is always regenerated, while the implementation file holds the custom business logic.
9
+
10
+ USE WHEN:
11
+ - The user wants to create or scaffold a processor, background job, or custom business-logic handler from a processor payload, e.g. "buat processor", "generate processor", "create background job", "scaffold business logic handler"
12
+ - The user has a processor payload JSON and wants the matching code generated into a backend project
13
+ - The user wants to re-generate a processor's routing while keeping their hand-written logic (re-run WITHOUT force preserves custom code)
14
+
15
+ DO NOT USE FOR:
16
+ - Generating a standard REST endpoint from a payload -> use 'codegen_create_endpoint'
17
+ - Generating a dashboard endpoint -> use 'codegen_create_dashboard'
18
+ - Generating a Kafka consumer -> use 'codegen_create_kafka_consumer'
19
+ - Generating a backend payload from a database table -> use 'codegen_generate_payload'
20
+
21
+ This tool runs: npx restforge processor create --project=<project> --name=<name> --payload=<payload> [--database] [--force] [--skip-sql-validation] in the given cwd.
22
+
23
+ Re-run behavior (important):
24
+ - WITHOUT 'force': the endpoint router + metadata are regenerated, but the processor implementation file is SKIPPED ("custom code preserved") — safe to re-run to refresh routing without losing hand-written logic.
25
+ - WITH 'force': the implementation file is archived first, then overwritten with a fresh scaffold — custom code survives only in the archive.
26
+
27
+ Preconditions:
28
+ - The project must have @restforgejs/platform installed in node_modules.
29
+ - The named processor payload JSON must exist. This tool does not pre-check it — if the CLI fails, the failure response surfaces the cause.
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. "generate the processor", "regenerate the routing").
34
+ - Speak in plain language; summarise the result. Do not paste raw CLI output unless the user explicitly asks.
35
+ - If the user wants to overwrite existing custom implementation, warn that without archiving they would lose hand-written logic; 'force' archives the old file before overwriting.
36
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
37
+ inputSchema: {
38
+ cwd: z
39
+ .string()
40
+ .min(1)
41
+ .describe('Absolute path of the backend project folder (must contain node_modules/@restforgejs/platform)'),
42
+ project: z.string().min(1).describe('Target project name. REQUIRED.'),
43
+ name: z.string().min(1).describe('Processor name (also the endpoint name). REQUIRED.'),
44
+ payload: z
45
+ .string()
46
+ .min(1)
47
+ .describe('Path or file name of the processor payload JSON. REQUIRED.'),
48
+ database: z
49
+ .enum(['postgres', 'mysql', 'oracle', 'sqlite'])
50
+ .optional()
51
+ .describe('Database type. When omitted, the CLI uses its default (postgres / auto-detect).'),
52
+ force: z
53
+ .boolean()
54
+ .optional()
55
+ .describe('Archive then overwrite an existing processor implementation file. Without it, the implementation file is preserved (only routing/metadata regenerate).'),
56
+ skipSqlValidation: z
57
+ .boolean()
58
+ .optional()
59
+ .describe('Skip SQL keyword validation. When omitted, the CLI validates SQL as usual.'),
60
+ },
61
+ annotations: {
62
+ title: 'Create Processor Module',
63
+ readOnlyHint: false,
64
+ idempotentHint: false,
65
+ destructiveHint: false,
66
+ },
67
+ }, async ({ cwd, project, name, payload, database, force, skipSqlValidation }) => {
68
+ const projectCwd = resolve(cwd);
69
+ try {
70
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
71
+ }
72
+ catch {
73
+ return {
74
+ content: [
75
+ {
76
+ type: 'text',
77
+ text: `Precondition not met: the RESTForge package is not installed in this project.
78
+
79
+ Project path: ${projectCwd}
80
+ Expected location: node_modules/@restforgejs/platform
81
+ Requested processor: ${name}
82
+ Requested payload: ${payload}
83
+
84
+ For the assistant:
85
+ - The user needs to install the RESTForge package before a processor can be generated.
86
+ - Suggest installing the package first, then retry. When explaining, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
87
+ },
88
+ ],
89
+ isError: false,
90
+ };
91
+ }
92
+ const args = ['restforge', 'processor', 'create', `--project=${project}`, `--name=${name}`, `--payload=${payload}`];
93
+ if (database)
94
+ args.push(`--database=${database}`);
95
+ if (force)
96
+ args.push('--force');
97
+ if (skipSqlValidation)
98
+ args.push('--skip-sql-validation');
99
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 60_000 });
100
+ if (!result.success) {
101
+ return {
102
+ content: [
103
+ {
104
+ type: 'text',
105
+ text: `Failed to create the processor.
106
+
107
+ Project path: ${projectCwd}
108
+ Project: ${project}
109
+ Processor: ${name}
110
+ Payload: ${payload}
111
+ Command: ${result.command}
112
+ Exit code: ${result.exitCode}
113
+
114
+ --- CLI output ---
115
+ stdout:
116
+ ${result.stdout}
117
+
118
+ stderr:
119
+ ${result.stderr}
120
+ --- end CLI output ---
121
+
122
+ For the assistant:
123
+ - Tell the user the processor was not generated successfully.
124
+ - Summarise the most likely cause from the CLI output in plain language (common causes: the payload file was not found, the payload is invalid, SQL validation failed, or the target project does not exist). Do not paste raw output unless the user asks.
125
+ - Offer to retry once the issue is resolved. Do not mention internal tool names.`,
126
+ },
127
+ ],
128
+ isError: true,
129
+ };
130
+ }
131
+ return {
132
+ content: [
133
+ {
134
+ type: 'text',
135
+ text: `Processor created.
136
+
137
+ Project path: ${projectCwd}
138
+ Project: ${project}
139
+ Processor: ${name}
140
+ Payload: ${payload}
141
+ Force: ${force ? 'yes (old implementation archived then overwritten)' : 'no (existing implementation preserved)'}
142
+ Command: ${result.command}
143
+
144
+ --- CLI output ---
145
+ ${result.stdout}
146
+ --- end CLI output ---
147
+
148
+ For the assistant:
149
+ - Confirm the processor was generated. Mention the endpoint routing/metadata was (re)generated.
150
+ - If this was a re-run without force, note that any existing custom implementation was preserved. If force was used, note the old implementation was archived before being overwritten.
151
+ - Keep the reply concise. Do not paste raw CLI output unless the user explicitly asks. Do not mention internal tool names.`,
152
+ },
153
+ ],
154
+ };
155
+ });
156
+ }
157
+ //# sourceMappingURL=create-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-processor.js","sourceRoot":"","sources":["../../../src/tools/codegen/create-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,UAAU,8BAA8B,CAAC,MAAiB;IAC9D,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;uGA4BoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,+FAA+F,CAAC;YAC5G,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gCAAgC,CAAC;YACrE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oDAAoD,CAAC;YACtF,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,4DAA4D,CAAC;YACzE,QAAQ,EAAE,CAAC;iBACR,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;iBAC/C,QAAQ,EAAE;iBACV,QAAQ,CAAC,iFAAiF,CAAC;YAC9F,KAAK,EAAE,CAAC;iBACL,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,wJAAwJ,CAAC;YACrK,iBAAiB,EAAE,CAAC;iBACjB,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,4EAA4E,CAAC;SAC1F;QACD,WAAW,EAAE;YACX,KAAK,EAAE,yBAAyB;YAChC,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK;SACvB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE;QAC5E,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;;uBAEH,IAAI;qBACN,OAAO;;;;sMAI0K;qBACzL;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,aAAa,OAAO,EAAE,EAAE,UAAU,IAAI,EAAE,EAAE,aAAa,OAAO,EAAE,CAAC,CAAC;QACpH,IAAI,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;QAClD,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,iBAAiB;YAAE,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAE1D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEpF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;WACf,OAAO;aACL,IAAI;WACN,OAAO;WACP,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;;;iFAMkE;qBACpE;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;WACf,OAAO;aACL,IAAI;WACN,OAAO;SACT,KAAK,CAAC,CAAC,CAAC,oDAAoD,CAAC,CAAC,CAAC,wCAAwC;WACrG,MAAM,CAAC,OAAO;;;EAGvB,MAAM,CAAC,MAAM;;;;;;2HAM4G;iBAChH;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 registerCodegenGenerateTest(server: McpServer): void;
@@ -0,0 +1,149 @@
1
+ import { z } from 'zod';
2
+ import { access } from 'node:fs/promises';
3
+ import { resolve, join } from 'node:path';
4
+ import { execProcess } from '../../lib/exec.js';
5
+ export function registerCodegenGenerateTest(server) {
6
+ server.registerTool('codegen_generate_test', {
7
+ title: 'Generate Integration Test',
8
+ description: `Generate a Jest + Supertest integration test file for an EXISTING endpoint, by wrapping restforge test generate.
9
+
10
+ USE WHEN:
11
+ - The user wants to generate, scaffold, or create an integration test for an existing endpoint, e.g. "generate test untuk endpoint", "buat integration test", "scaffold jest test", "create supertest test"
12
+ - The user just generated an endpoint and now wants its test
13
+ - The user wants to initialise the Jest test-data configuration for a project (with 'init')
14
+
15
+ DO NOT USE FOR:
16
+ - Generating the endpoint itself -> use 'codegen_create_endpoint'
17
+ - Running the tests -> out of scope (the user runs the generated tests with their own test runner)
18
+ - Validating a payload or SQL -> use 'codegen_validate_payload' / 'codegen_validate_sql'
19
+
20
+ This tool runs: npx restforge test generate --project=<project> --endpoint=<endpoint> [--port] [--init] [--force] in the given cwd.
21
+
22
+ Preconditions:
23
+ - The project must have @restforgejs/platform installed in node_modules.
24
+ - The named endpoint must already exist in the project. This tool does not pre-check it — if the CLI fails, the failure response surfaces the cause.
25
+
26
+ PRESENTATION GUIDANCE:
27
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
28
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "generate the integration test").
29
+ - Speak in plain language; summarise the result. Do not paste raw CLI output unless the user explicitly asks.
30
+ - On the first test for a project, suggest using 'init' to set up the Jest test-data configuration.
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 backend project folder (must contain node_modules/@restforgejs/platform)'),
37
+ project: z.string().min(1).describe('Target project name. REQUIRED.'),
38
+ endpoint: z.string().min(1).describe('Name of the existing endpoint to test. REQUIRED.'),
39
+ port: z
40
+ .number()
41
+ .int()
42
+ .min(1)
43
+ .max(65535)
44
+ .optional()
45
+ .describe('Server port used when the test runs. When omitted, the CLI uses its default (3000).'),
46
+ init: z
47
+ .boolean()
48
+ .optional()
49
+ .describe('Initialise the Jest test-data configuration (global + per-endpoint) if not present. Use on the first test for a project.'),
50
+ force: z
51
+ .boolean()
52
+ .optional()
53
+ .describe('Overwrite an existing test file. Without it, the command will not replace an existing test.'),
54
+ },
55
+ annotations: {
56
+ title: 'Generate Integration Test',
57
+ readOnlyHint: false,
58
+ idempotentHint: false,
59
+ destructiveHint: false,
60
+ },
61
+ }, async ({ cwd, project, endpoint, port, init, force }) => {
62
+ const projectCwd = resolve(cwd);
63
+ try {
64
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
65
+ }
66
+ catch {
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: `Precondition not met: the RESTForge package is not installed in this project.
72
+
73
+ Project path: ${projectCwd}
74
+ Expected location: node_modules/@restforgejs/platform
75
+ Requested endpoint: ${endpoint}
76
+
77
+ For the assistant:
78
+ - The user needs to install the RESTForge package before an integration test can be generated.
79
+ - Suggest installing the package first, then retry. When explaining, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
80
+ },
81
+ ],
82
+ isError: false,
83
+ };
84
+ }
85
+ const args = ['restforge', 'test', 'generate', `--project=${project}`, `--endpoint=${endpoint}`];
86
+ if (port !== undefined)
87
+ args.push(`--port=${port}`);
88
+ if (init)
89
+ args.push('--init');
90
+ if (force)
91
+ args.push('--force');
92
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 60_000 });
93
+ if (!result.success) {
94
+ return {
95
+ content: [
96
+ {
97
+ type: 'text',
98
+ text: `Failed to generate the integration test.
99
+
100
+ Project path: ${projectCwd}
101
+ Project: ${project}
102
+ Endpoint: ${endpoint}
103
+ Command: ${result.command}
104
+ Exit code: ${result.exitCode}
105
+
106
+ --- CLI output ---
107
+ stdout:
108
+ ${result.stdout}
109
+
110
+ stderr:
111
+ ${result.stderr}
112
+ --- end CLI output ---
113
+
114
+ For the assistant:
115
+ - Tell the user the integration test was not generated successfully.
116
+ - Summarise the most likely cause from the CLI output in plain language (common causes: the endpoint does not exist yet, the project does not exist, or an existing test blocks generation without force). Do not paste raw output unless the user asks.
117
+ - Offer to retry once the issue is resolved. Do not mention internal tool names.`,
118
+ },
119
+ ],
120
+ isError: true,
121
+ };
122
+ }
123
+ return {
124
+ content: [
125
+ {
126
+ type: 'text',
127
+ text: `Integration test generated.
128
+
129
+ Project path: ${projectCwd}
130
+ Project: ${project}
131
+ Endpoint: ${endpoint}
132
+ Port: ${port ?? 'default (3000)'}
133
+ Init: ${init ? 'yes' : 'no'}
134
+ Command: ${result.command}
135
+
136
+ --- CLI output ---
137
+ ${result.stdout}
138
+ --- end CLI output ---
139
+
140
+ For the assistant:
141
+ - Confirm the Jest + Supertest integration test was generated for the endpoint.
142
+ - Mention the user runs the test with their own test runner; this server does not run it.
143
+ - Keep the reply concise. Do not paste raw CLI output unless the user explicitly asks. Do not mention internal tool names.`,
144
+ },
145
+ ],
146
+ };
147
+ });
148
+ }
149
+ //# sourceMappingURL=generate-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-test.js","sourceRoot":"","sources":["../../../src/tools/codegen/generate-test.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,9 @@ import { registerCodegenGetQueryDeclarativeCatalog } from './get-query-declarati
8
8
  import { registerCodegenGetDashboardCatalog } from './get-dashboard-catalog.js';
9
9
  import { registerCodegenCreateEndpoint } from './create-endpoint.js';
10
10
  import { registerCodegenCreateDashboard } from './create-dashboard.js';
11
+ import { registerCodegenCreateProcessor } from './create-processor.js';
12
+ import { registerCodegenCreateKafkaConsumer } from './create-kafka-consumer.js';
13
+ import { registerCodegenGenerateTest } from './generate-test.js';
11
14
  import { registerCodegenValidateDashboardPayload } from './validate-dashboard-payload.js';
12
15
  import { registerCodegenListTables } from './list-tables.js';
13
16
  import { registerCodegenDescribeTable } from './describe-table.js';
@@ -33,6 +36,9 @@ export function registerCodegenTools(server) {
33
36
  registerCodegenGetDashboardCatalog(server);
34
37
  registerCodegenCreateEndpoint(server);
35
38
  registerCodegenCreateDashboard(server);
39
+ registerCodegenCreateProcessor(server);
40
+ registerCodegenCreateKafkaConsumer(server);
41
+ registerCodegenGenerateTest(server);
36
42
  registerCodegenValidateDashboardPayload(server);
37
43
  registerCodegenListTables(server);
38
44
  registerCodegenDescribeTable(server);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/codegen/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,wCAAwC,EAAE,MAAM,mCAAmC,CAAC;AAC7F,OAAO,EAAE,yCAAyC,EAAE,MAAM,oCAAoC,CAAC;AAC/F,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,uCAAuC,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACvC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACvC,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,wCAAwC,CAAC,MAAM,CAAC,CAAC;IACjD,yCAAyC,CAAC,MAAM,CAAC,CAAC;IAClD,kCAAkC,CAAC,MAAM,CAAC,CAAC;IAC3C,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACvC,uCAAuC,CAAC,MAAM,CAAC,CAAC;IAChD,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClC,4BAA4B,CAAC,MAAM,CAAC,CAAC;IACrC,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,iCAAiC,CAAC,MAAM,CAAC,CAAC;IAC1C,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACxC,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACtC,kCAAkC,CAAC,MAAM,CAAC,CAAC;IAC3C,iCAAiC,CAAC,MAAM,CAAC,CAAC;IAC1C,8BAA8B,CAAC,MAAM,CAAC,CAAC;IACvC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,4BAA4B,CAAC,MAAM,CAAC,CAAC;IACrC,+BAA+B,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/codegen/index.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,10 @@ export function registerCodegenMigratePayload(server) {
7
7
  title: 'Migrate Payload (RDF backend -> UDF frontend)',
8
8
  description: `Convert an existing backend payload file (RDF) into a frontend payload (UDF) for RESTForge Designer, by wrapping restforge payload migrate. The output is always a SPLIT multi-file set written into an output directory (app-config.json, one file per page under pages/, and an aggregator <appCode>.json), not a single UDF file. The migrator also auto-discovers JOINed tables, so one JOINed RDF can produce several pages at once.
9
9
 
10
+ PRIMARY PATH TO CREATE A UDF (firm): this is the FIRST and preferred way to produce a UDF. RESTForge is backend-first — a UDF is normally DERIVED from an existing backend RDF via this tool, not written by hand. Whenever a backend RDF payload exists and the user wants a UDF/frontend, START HERE. Only hand-author a UDF from scratch (grounded by 'designer_get_udf_catalog') when there is genuinely no RDF to migrate from.
11
+
10
12
  USE WHEN:
13
+ - The user wants to CREATE or start a frontend UDF and a backend RDF payload exists — this is the default on-ramp, before any hand-authoring
11
14
  - The user wants to build a frontend UDF from an existing backend payload, e.g. "buat UDF dari payload backend", "konversi RDF ke UDF", "migrate payload ke frontend", "bikin payload designer dari backend existing"
12
15
  - The user has a working backend payload and now wants to start authoring the matching frontend in RESTForge Designer (on-ramp from backend to frontend)
13
16
  - The user mentions migrating, converting, or porting a backend payload over to the designer / frontend side