@restforgejs/mcp-server 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +149 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/env-parser.d.ts +30 -0
- package/dist/lib/env-parser.js +150 -0
- package/dist/lib/env-parser.js.map +1 -0
- package/dist/lib/exec.d.ts +29 -0
- package/dist/lib/exec.js +38 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +220 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/codegen/create-dashboard.d.ts +2 -0
- package/dist/tools/codegen/create-dashboard.js +256 -0
- package/dist/tools/codegen/create-dashboard.js.map +1 -0
- package/dist/tools/codegen/create-endpoint.d.ts +2 -0
- package/dist/tools/codegen/create-endpoint.js +263 -0
- package/dist/tools/codegen/create-endpoint.js.map +1 -0
- package/dist/tools/codegen/dbschema-generate-ddl.d.ts +2 -0
- package/dist/tools/codegen/dbschema-generate-ddl.js +187 -0
- package/dist/tools/codegen/dbschema-generate-ddl.js.map +1 -0
- package/dist/tools/codegen/dbschema-init.d.ts +2 -0
- package/dist/tools/codegen/dbschema-init.js +158 -0
- package/dist/tools/codegen/dbschema-init.js.map +1 -0
- package/dist/tools/codegen/dbschema-introspect.d.ts +2 -0
- package/dist/tools/codegen/dbschema-introspect.js +241 -0
- package/dist/tools/codegen/dbschema-introspect.js.map +1 -0
- package/dist/tools/codegen/dbschema-migrate.d.ts +2 -0
- package/dist/tools/codegen/dbschema-migrate.js +219 -0
- package/dist/tools/codegen/dbschema-migrate.js.map +1 -0
- package/dist/tools/codegen/dbschema-models.d.ts +2 -0
- package/dist/tools/codegen/dbschema-models.js +146 -0
- package/dist/tools/codegen/dbschema-models.js.map +1 -0
- package/dist/tools/codegen/dbschema-validate.d.ts +2 -0
- package/dist/tools/codegen/dbschema-validate.js +153 -0
- package/dist/tools/codegen/dbschema-validate.js.map +1 -0
- package/dist/tools/codegen/describe-table.d.ts +2 -0
- package/dist/tools/codegen/describe-table.js +259 -0
- package/dist/tools/codegen/describe-table.js.map +1 -0
- package/dist/tools/codegen/diff-payload.d.ts +2 -0
- package/dist/tools/codegen/diff-payload.js +165 -0
- package/dist/tools/codegen/diff-payload.js.map +1 -0
- package/dist/tools/codegen/generate-payload.d.ts +2 -0
- package/dist/tools/codegen/generate-payload.js +145 -0
- package/dist/tools/codegen/generate-payload.js.map +1 -0
- package/dist/tools/codegen/get-dashboard-catalog.d.ts +2 -0
- package/dist/tools/codegen/get-dashboard-catalog.js +213 -0
- package/dist/tools/codegen/get-dashboard-catalog.js.map +1 -0
- package/dist/tools/codegen/get-dbschema-catalog.d.ts +2 -0
- package/dist/tools/codegen/get-dbschema-catalog.js +244 -0
- package/dist/tools/codegen/get-dbschema-catalog.js.map +1 -0
- package/dist/tools/codegen/get-field-validation-catalog.d.ts +2 -0
- package/dist/tools/codegen/get-field-validation-catalog.js +186 -0
- package/dist/tools/codegen/get-field-validation-catalog.js.map +1 -0
- package/dist/tools/codegen/get-query-declarative-catalog.d.ts +2 -0
- package/dist/tools/codegen/get-query-declarative-catalog.js +200 -0
- package/dist/tools/codegen/get-query-declarative-catalog.js.map +1 -0
- package/dist/tools/codegen/index.d.ts +2 -0
- package/dist/tools/codegen/index.js +43 -0
- package/dist/tools/codegen/index.js.map +1 -0
- package/dist/tools/codegen/list-tables.d.ts +2 -0
- package/dist/tools/codegen/list-tables.js +220 -0
- package/dist/tools/codegen/list-tables.js.map +1 -0
- package/dist/tools/codegen/sync-payload.d.ts +2 -0
- package/dist/tools/codegen/sync-payload.js +177 -0
- package/dist/tools/codegen/sync-payload.js.map +1 -0
- package/dist/tools/codegen/validate-dashboard-payload.d.ts +2 -0
- package/dist/tools/codegen/validate-dashboard-payload.js +239 -0
- package/dist/tools/codegen/validate-dashboard-payload.js.map +1 -0
- package/dist/tools/codegen/validate-payload.d.ts +2 -0
- package/dist/tools/codegen/validate-payload.js +166 -0
- package/dist/tools/codegen/validate-payload.js.map +1 -0
- package/dist/tools/codegen/validate-sql.d.ts +2 -0
- package/dist/tools/codegen/validate-sql.js +270 -0
- package/dist/tools/codegen/validate-sql.js.map +1 -0
- package/dist/tools/health/index.d.ts +2 -0
- package/dist/tools/health/index.js +5 -0
- package/dist/tools/health/index.js.map +1 -0
- package/dist/tools/health/ping.d.ts +2 -0
- package/dist/tools/health/ping.js +68 -0
- package/dist/tools/health/ping.js.map +1 -0
- package/dist/tools/runtime/check-launcher-exists.d.ts +2 -0
- package/dist/tools/runtime/check-launcher-exists.js +111 -0
- package/dist/tools/runtime/check-launcher-exists.js.map +1 -0
- package/dist/tools/runtime/check-status.d.ts +2 -0
- package/dist/tools/runtime/check-status.js +417 -0
- package/dist/tools/runtime/check-status.js.map +1 -0
- package/dist/tools/runtime/detect-config.d.ts +2 -0
- package/dist/tools/runtime/detect-config.js +130 -0
- package/dist/tools/runtime/detect-config.js.map +1 -0
- package/dist/tools/runtime/detect-project.d.ts +2 -0
- package/dist/tools/runtime/detect-project.js +132 -0
- package/dist/tools/runtime/detect-project.js.map +1 -0
- package/dist/tools/runtime/generate-launcher.d.ts +2 -0
- package/dist/tools/runtime/generate-launcher.js +438 -0
- package/dist/tools/runtime/generate-launcher.js.map +1 -0
- package/dist/tools/runtime/index.d.ts +2 -0
- package/dist/tools/runtime/index.js +15 -0
- package/dist/tools/runtime/index.js.map +1 -0
- package/dist/tools/runtime/validate-preflight.d.ts +2 -0
- package/dist/tools/runtime/validate-preflight.js +209 -0
- package/dist/tools/runtime/validate-preflight.js.map +1 -0
- package/dist/tools/setup/create-folder.d.ts +2 -0
- package/dist/tools/setup/create-folder.js +138 -0
- package/dist/tools/setup/create-folder.js.map +1 -0
- package/dist/tools/setup/get-config-schema.d.ts +2 -0
- package/dist/tools/setup/get-config-schema.js +158 -0
- package/dist/tools/setup/get-config-schema.js.map +1 -0
- package/dist/tools/setup/get-init-template.d.ts +2 -0
- package/dist/tools/setup/get-init-template.js +130 -0
- package/dist/tools/setup/get-init-template.js.map +1 -0
- package/dist/tools/setup/index.d.ts +2 -0
- package/dist/tools/setup/index.js +21 -0
- package/dist/tools/setup/index.js.map +1 -0
- package/dist/tools/setup/init-config.d.ts +2 -0
- package/dist/tools/setup/init-config.js +120 -0
- package/dist/tools/setup/init-config.js.map +1 -0
- package/dist/tools/setup/install-package.d.ts +2 -0
- package/dist/tools/setup/install-package.js +133 -0
- package/dist/tools/setup/install-package.js.map +1 -0
- package/dist/tools/setup/read-env.d.ts +2 -0
- package/dist/tools/setup/read-env.js +138 -0
- package/dist/tools/setup/read-env.js.map +1 -0
- package/dist/tools/setup/update-env.d.ts +2 -0
- package/dist/tools/setup/update-env.js +176 -0
- package/dist/tools/setup/update-env.js.map +1 -0
- package/dist/tools/setup/validate-config.d.ts +2 -0
- package/dist/tools/setup/validate-config.js +138 -0
- package/dist/tools/setup/validate-config.js.map +1 -0
- package/dist/tools/setup/write-env.d.ts +2 -0
- package/dist/tools/setup/write-env.js +168 -0
- package/dist/tools/setup/write-env.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,130 @@
|
|
|
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 registerSetupGetInitTemplate(server) {
|
|
6
|
+
server.registerTool('setup_get_init_template', {
|
|
7
|
+
title: 'Get Init Template',
|
|
8
|
+
description: `Get raw template content of db-connection.env without writing any file.
|
|
9
|
+
Useful as reference after current file has been modified, or for comparing
|
|
10
|
+
current config against template defaults (drift detection).
|
|
11
|
+
|
|
12
|
+
USE WHEN:
|
|
13
|
+
- The agent needs to see template defaults after the current file has been modified
|
|
14
|
+
- Comparing current config with template (drift detection)
|
|
15
|
+
- Restoring template content reference without re-running init
|
|
16
|
+
- The user asks things like "show me the default template", "lihat template config default",
|
|
17
|
+
"apa isi template defaultnya", "what does the default config look like",
|
|
18
|
+
"bandingkan dengan template asli", "compare against the original template"
|
|
19
|
+
|
|
20
|
+
DO NOT USE FOR:
|
|
21
|
+
- Generating new config files in the project -> use 'setup_init_config'
|
|
22
|
+
- Reading current config -> use 'setup_read_env'
|
|
23
|
+
- Getting structured schema (JSON) -> use 'setup_get_config_schema'
|
|
24
|
+
|
|
25
|
+
This tool runs: npx restforge config:template in the given cwd.
|
|
26
|
+
This tool is READ-ONLY and safe to call repeatedly. No file is written.
|
|
27
|
+
Requires @restforgejs/platform >= 2.3.1.
|
|
28
|
+
|
|
29
|
+
PRESENTATION GUIDANCE:
|
|
30
|
+
- Match the user's language. If the user writes in Indonesian, respond in Indonesian.
|
|
31
|
+
- Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "install the package", "set up the initial config", "show the active configuration").
|
|
32
|
+
- Speak in plain language. Summarise what the template contains (sections present, total parameters); do not paste the entire template body unless the user explicitly asks for it.
|
|
33
|
+
- When a precondition is not met (e.g. the package is not installed), frame it as a question or next-step suggestion rather than an error.`,
|
|
34
|
+
inputSchema: {
|
|
35
|
+
cwd: z.string().min(1).describe('Absolute path of the project folder (must have @restforgejs/platform installed in node_modules)'),
|
|
36
|
+
},
|
|
37
|
+
annotations: {
|
|
38
|
+
title: 'Get Init Template',
|
|
39
|
+
readOnlyHint: true,
|
|
40
|
+
idempotentHint: true,
|
|
41
|
+
},
|
|
42
|
+
}, async ({ cwd }) => {
|
|
43
|
+
const projectCwd = resolve(cwd);
|
|
44
|
+
// Precondition check: @restforgejs/platform must be installed before this CLI command can run.
|
|
45
|
+
// Treated as a non-error precondition per the authoring guide §3.4.
|
|
46
|
+
try {
|
|
47
|
+
await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: `Precondition not met: the RESTForge package is not installed in this project.
|
|
55
|
+
|
|
56
|
+
Project path: ${projectCwd}
|
|
57
|
+
Expected location: node_modules/@restforgejs/platform
|
|
58
|
+
|
|
59
|
+
For the assistant:
|
|
60
|
+
- The default config template can only be retrieved once the RESTForge package is installed locally.
|
|
61
|
+
- Suggest installing the package first, then retry getting the template.
|
|
62
|
+
- When explaining to the user, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
isError: false, // per §3.4
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Run subprocess with NODE_ENV=production to suppress legacy banner output.
|
|
69
|
+
// stripFinalNewline=false to preserve byte-perfect template content
|
|
70
|
+
// (matches the trailing newline in db-connection.env file written by `restforge init`).
|
|
71
|
+
const result = await execProcess('npx', ['restforge', 'config', 'template'], {
|
|
72
|
+
cwd: projectCwd,
|
|
73
|
+
timeout: 15_000,
|
|
74
|
+
env: { NODE_ENV: 'production' },
|
|
75
|
+
stripFinalNewline: false,
|
|
76
|
+
});
|
|
77
|
+
// CLI failure: real error per §3.4; structured per §3.5.
|
|
78
|
+
if (!result.success) {
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: `Failed to retrieve the configuration template.
|
|
84
|
+
|
|
85
|
+
Project path: ${projectCwd}
|
|
86
|
+
Command: ${result.command}
|
|
87
|
+
Exit code: ${result.exitCode}
|
|
88
|
+
|
|
89
|
+
--- CLI output ---
|
|
90
|
+
stdout:
|
|
91
|
+
${result.stdout}
|
|
92
|
+
|
|
93
|
+
stderr:
|
|
94
|
+
${result.stderr}
|
|
95
|
+
--- end CLI output ---
|
|
96
|
+
|
|
97
|
+
For the assistant:
|
|
98
|
+
- Tell the user that the default template could not be retrieved.
|
|
99
|
+
- A common cause is an older RESTForge version that does not yet expose the template command (requires @restforgejs/platform >= 2.3.1). Suggest upgrading the package as a likely fix.
|
|
100
|
+
- Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.`,
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
isError: true, // per §3.4
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Success: one-line summary + labeled facts + fenced template body per §3.5.
|
|
107
|
+
return {
|
|
108
|
+
content: [
|
|
109
|
+
{
|
|
110
|
+
type: 'text',
|
|
111
|
+
text: `Configuration template retrieved successfully.
|
|
112
|
+
|
|
113
|
+
Project path: ${projectCwd}
|
|
114
|
+
Source: restforge (matches the template that 'init' would write into config/db-connection.env)
|
|
115
|
+
Note: this is a read-only preview; no file was written.
|
|
116
|
+
|
|
117
|
+
--- Template (db-connection.env) ---
|
|
118
|
+
${result.stdout}--- end Template (db-connection.env) ---
|
|
119
|
+
|
|
120
|
+
For the assistant:
|
|
121
|
+
- Confirm to the user that the default template is available.
|
|
122
|
+
- Summarise the template in plain language: which sections are present (database, license, optional Live Sync / Redis / Kafka / Logging) and the total parameter count.
|
|
123
|
+
- Do not paste the full template body unless the user explicitly asks for it. If the user is doing drift detection, the full template content is available between the fenced markers above for programmatic comparison.
|
|
124
|
+
- Do not mention internal tool names.`,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=get-init-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-init-template.js","sourceRoot":"","sources":["../../../src/tools/setup/get-init-template.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,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;2IAyBwH;QACrI,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iGAAiG,CAAC;SACnI;QACD,WAAW,EAAE;YACX,KAAK,EAAE,mBAAmB;YAC1B,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;QAChB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAEhC,+FAA+F;QAC/F,oEAAoE;QACpE,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;;;;;;gKAMsI;qBACnJ;iBACF;gBACD,OAAO,EAAE,KAAK,EAAE,WAAW;aAC5B,CAAC;QACJ,CAAC;QAED,4EAA4E;QAC5E,oEAAoE;QACpE,wFAAwF;QACxF,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,KAAK,EACL,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,CAAC,EACnC;YACE,GAAG,EAAE,UAAU;YACf,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE;YAC/B,iBAAiB,EAAE,KAAK;SACzB,CACF,CAAC;QAEF,yDAAyD;QACzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;WACf,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;;;0GAM2F;qBAC7F;iBACF;gBACD,OAAO,EAAE,IAAI,EAAE,WAAW;aAC3B,CAAC;QACJ,CAAC;QAED,6EAA6E;QAC7E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;;;;;EAKxB,MAAM,CAAC,MAAM;;;;;;sCAMuB;iBAC3B;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { registerSetupCreateFolder } from './create-folder.js';
|
|
2
|
+
import { registerSetupInstallPackage } from './install-package.js';
|
|
3
|
+
import { registerSetupInitConfig } from './init-config.js';
|
|
4
|
+
import { registerSetupWriteEnv } from './write-env.js';
|
|
5
|
+
import { registerSetupReadEnv } from './read-env.js';
|
|
6
|
+
import { registerSetupUpdateEnv } from './update-env.js';
|
|
7
|
+
import { registerSetupValidateConfig } from './validate-config.js';
|
|
8
|
+
import { registerSetupGetConfigSchema } from './get-config-schema.js';
|
|
9
|
+
import { registerSetupGetInitTemplate } from './get-init-template.js';
|
|
10
|
+
export function registerSetupTools(server) {
|
|
11
|
+
registerSetupCreateFolder(server);
|
|
12
|
+
registerSetupInstallPackage(server);
|
|
13
|
+
registerSetupInitConfig(server);
|
|
14
|
+
registerSetupWriteEnv(server);
|
|
15
|
+
registerSetupReadEnv(server);
|
|
16
|
+
registerSetupUpdateEnv(server);
|
|
17
|
+
registerSetupValidateConfig(server);
|
|
18
|
+
registerSetupGetConfigSchema(server);
|
|
19
|
+
registerSetupGetInitTemplate(server);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/setup/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClC,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,4BAA4B,CAAC,MAAM,CAAC,CAAC;IACrC,4BAA4B,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
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 registerSetupInitConfig(server) {
|
|
6
|
+
server.registerTool('setup_init_config', {
|
|
7
|
+
title: 'Init RESTForge Config',
|
|
8
|
+
description: `Generate skeleton config and sample payloads in the project folder via restforge.
|
|
9
|
+
|
|
10
|
+
USE WHEN:
|
|
11
|
+
- The project has @restforgejs/platform installed in node_modules
|
|
12
|
+
- The config/ and payload/ folders do not exist yet, or you want to reset them to the default template
|
|
13
|
+
- Starting RESTForge project configuration from scratch
|
|
14
|
+
|
|
15
|
+
DO NOT USE FOR:
|
|
16
|
+
- Installing @restforgejs/platform -> use 'setup_install_package'
|
|
17
|
+
- Filling in credentials in db-connection.env -> use 'setup_write_env'
|
|
18
|
+
|
|
19
|
+
This tool runs: npx restforge init in the given cwd.
|
|
20
|
+
Output: config/db-connection.env (empty template), payload/samples.json, payload/query/samples-datatables.sql.
|
|
21
|
+
|
|
22
|
+
PRESENTATION GUIDANCE:
|
|
23
|
+
- Match the user's language. If the user writes in Indonesian, respond in Indonesian.
|
|
24
|
+
- Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "install the package", "fill in the credentials").
|
|
25
|
+
- Speak in plain language. Summarise the result; do not paste raw CLI output unless the user explicitly asks.
|
|
26
|
+
- When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
|
|
27
|
+
inputSchema: {
|
|
28
|
+
cwd: z
|
|
29
|
+
.string()
|
|
30
|
+
.min(1)
|
|
31
|
+
.describe('Absolute path of the project folder'),
|
|
32
|
+
},
|
|
33
|
+
annotations: {
|
|
34
|
+
title: 'Init Config',
|
|
35
|
+
readOnlyHint: false,
|
|
36
|
+
idempotentHint: false,
|
|
37
|
+
},
|
|
38
|
+
}, async ({ cwd }) => {
|
|
39
|
+
const projectCwd = resolve(cwd);
|
|
40
|
+
// Precondition check: @restforgejs/platform must be present in node_modules.
|
|
41
|
+
// Treated as a non-error precondition per the authoring guide §3.4.
|
|
42
|
+
try {
|
|
43
|
+
await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: 'text',
|
|
50
|
+
text: `Precondition not met: the RESTForge package is not installed in this project.
|
|
51
|
+
|
|
52
|
+
Project path: ${projectCwd}
|
|
53
|
+
Expected location: node_modules/@restforgejs/platform
|
|
54
|
+
|
|
55
|
+
For the assistant:
|
|
56
|
+
- The user needs to install the RESTForge package before the initial config can be generated.
|
|
57
|
+
- Use the appropriate package-installation tool to do this, then retry generating the config.
|
|
58
|
+
- When explaining to the user, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
isError: false,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const result = await execProcess('npx', ['restforge', 'init'], { cwd: projectCwd, timeout: 30_000 });
|
|
65
|
+
// CLI failure: real error per §3.4; structured per §3.5.
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: `Failed to generate the initial RESTForge configuration.
|
|
72
|
+
|
|
73
|
+
Project path: ${projectCwd}
|
|
74
|
+
Command: ${result.command}
|
|
75
|
+
Exit code: ${result.exitCode}
|
|
76
|
+
|
|
77
|
+
--- CLI output ---
|
|
78
|
+
stdout:
|
|
79
|
+
${result.stdout}
|
|
80
|
+
|
|
81
|
+
stderr:
|
|
82
|
+
${result.stderr}
|
|
83
|
+
--- end CLI output ---
|
|
84
|
+
|
|
85
|
+
For the assistant:
|
|
86
|
+
- Tell the user that the initialisation command did not complete successfully.
|
|
87
|
+
- Summarise the likely cause from the CLI output in plain language; do not paste the raw stdout/stderr unless the user explicitly asks for it.
|
|
88
|
+
- Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
isError: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// Success: one-line summary + labeled facts + fenced raw output per §3.5.
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: 'text',
|
|
99
|
+
text: `Initial RESTForge configuration generated successfully.
|
|
100
|
+
|
|
101
|
+
Project path: ${projectCwd}
|
|
102
|
+
Files created:
|
|
103
|
+
- config/db-connection.env (empty template, awaiting credentials)
|
|
104
|
+
- payload/samples.json
|
|
105
|
+
- payload/query/samples-datatables.sql
|
|
106
|
+
|
|
107
|
+
--- CLI output ---
|
|
108
|
+
${result.stdout}
|
|
109
|
+
--- end CLI output ---
|
|
110
|
+
|
|
111
|
+
For the assistant:
|
|
112
|
+
- Confirm to the user that the project skeleton is ready.
|
|
113
|
+
- Suggest the next step in plain words: the credentials file (license and database connection) still needs to be filled in before the project can run.
|
|
114
|
+
- Keep the reply concise. Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names.`,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=init-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-config.js","sourceRoot":"","sources":["../../../src/tools/setup/init-config.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,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE;;;;;;;;;;;;;;;;;;uGAkBoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,qCAAqC,CAAC;SACnD;QACD,WAAW,EAAE;YACX,KAAK,EAAE,aAAa;YACpB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;SACtB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;QAChB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAEhC,6EAA6E;QAC7E,oEAAoE;QACpE,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;;;;;;gKAMsI;qBACnJ;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,KAAK,EACL,CAAC,WAAW,EAAE,MAAM,CAAC,EACrB,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CACrC,CAAC;QAEF,yDAAyD;QACzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;WACf,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;;;4FAM6E;qBAC/E;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,0EAA0E;QAC1E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;;;;;;;EAOxB,MAAM,CAAC,MAAM;;;;;;+HAMgH;iBACpH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { access } from 'node:fs/promises';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { execProcess } from '../../lib/exec.js';
|
|
5
|
+
export function registerSetupInstallPackage(server) {
|
|
6
|
+
server.registerTool('setup_install_package', {
|
|
7
|
+
title: 'Install @restforgejs/platform Package',
|
|
8
|
+
description: `Install the @restforgejs/platform package into the project's node_modules via npm.
|
|
9
|
+
|
|
10
|
+
USE WHEN:
|
|
11
|
+
- The user wants to install RESTForge (@restforgejs/platform) into a project
|
|
12
|
+
- The project folder exists but does not yet have @restforgejs/platform in node_modules
|
|
13
|
+
- Setting up a new project before the configuration stage
|
|
14
|
+
- Updating @restforgejs/platform to a specific tag or version
|
|
15
|
+
- The user says things like "install restforge", "tambahkan @restforgejs/platform",
|
|
16
|
+
"pasang package restforge", "set up the package", "siapkan project ini",
|
|
17
|
+
"upgrade @restforgejs/platform", "ganti versi restforge"
|
|
18
|
+
|
|
19
|
+
DO NOT USE FOR:
|
|
20
|
+
- Creating a new project folder -> use 'setup_create_folder'
|
|
21
|
+
- Generating config skeleton -> use 'setup_init_config'
|
|
22
|
+
- Filling in credentials -> use 'setup_write_env'
|
|
23
|
+
- Validating the configuration -> use 'setup_validate_config'
|
|
24
|
+
|
|
25
|
+
This tool sits in the middle of the new-project setup chain: typically run
|
|
26
|
+
after 'setup_create_folder' creates the project folder, and before
|
|
27
|
+
'setup_init_config' which generates the configuration skeleton. 'setup_init_config'
|
|
28
|
+
will return a precondition message if this tool has not been run first. // per §5.2
|
|
29
|
+
|
|
30
|
+
This tool runs: npm install @restforgejs/platform@<version> in the given cwd (local install, not global).
|
|
31
|
+
Default version is "beta" because RESTForge is currently a public pre-release. Use "latest" once stable, or a specific version (e.g. "1.2.3").
|
|
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. "create the project folder", "generate the initial config", "fill in the credentials").
|
|
36
|
+
- Speak in plain language. Summarise the result; do not paste raw npm output unless the user explicitly asks.
|
|
37
|
+
- When a precondition is not met (e.g. the project folder is missing), frame it as a question or next-step suggestion rather than an error.`,
|
|
38
|
+
inputSchema: {
|
|
39
|
+
cwd: z
|
|
40
|
+
.string()
|
|
41
|
+
.min(1)
|
|
42
|
+
.describe('Absolute path of the project folder (must exist before this tool runs)'),
|
|
43
|
+
version: z
|
|
44
|
+
.string()
|
|
45
|
+
.default('beta')
|
|
46
|
+
.describe('npm version or tag: "beta" (default), "latest", or a specific version (e.g. "1.2.3")'),
|
|
47
|
+
},
|
|
48
|
+
annotations: {
|
|
49
|
+
title: 'Install @restforgejs/platform',
|
|
50
|
+
readOnlyHint: false,
|
|
51
|
+
idempotentHint: true,
|
|
52
|
+
},
|
|
53
|
+
}, async ({ cwd, version }) => {
|
|
54
|
+
const projectCwd = resolve(cwd);
|
|
55
|
+
// Precondition check: the project folder must exist.
|
|
56
|
+
// Treated as a non-error precondition per the authoring guide §3.4.
|
|
57
|
+
try {
|
|
58
|
+
await access(projectCwd);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return {
|
|
62
|
+
content: [
|
|
63
|
+
{
|
|
64
|
+
type: 'text',
|
|
65
|
+
text: `Precondition not met: the project folder does not exist yet.
|
|
66
|
+
|
|
67
|
+
Project path: ${projectCwd}
|
|
68
|
+
|
|
69
|
+
For the assistant:
|
|
70
|
+
- The user is trying to install the RESTForge package into a folder that has not been created yet.
|
|
71
|
+
- Suggest creating the project folder first, then retry the installation.
|
|
72
|
+
- When explaining to the user, say something like "the project folder isn't there yet — should I create it first?". Do not mention internal tool names.`,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
isError: false, // per §3.4
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const result = await execProcess('npm', ['install', `@restforgejs/platform@${version}`], { cwd: projectCwd, timeout: 180_000 });
|
|
79
|
+
// CLI failure: real error per §3.4; structured per §3.5.
|
|
80
|
+
if (!result.success) {
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: 'text',
|
|
85
|
+
text: `Failed to install the RESTForge package.
|
|
86
|
+
|
|
87
|
+
Project path: ${projectCwd}
|
|
88
|
+
Requested version: ${version}
|
|
89
|
+
Command: ${result.command}
|
|
90
|
+
Exit code: ${result.exitCode}
|
|
91
|
+
|
|
92
|
+
--- npm output ---
|
|
93
|
+
stdout:
|
|
94
|
+
${result.stdout}
|
|
95
|
+
|
|
96
|
+
stderr:
|
|
97
|
+
${result.stderr}
|
|
98
|
+
--- end npm output ---
|
|
99
|
+
|
|
100
|
+
For the assistant:
|
|
101
|
+
- Tell the user that the installation did not complete successfully.
|
|
102
|
+
- Summarise the likely cause from the npm output in plain language (network, registry, version not found, peer dependency); do not paste the raw stdout/stderr unless the user explicitly asks.
|
|
103
|
+
- Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
isError: true, // per §3.4
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Success: one-line summary + labeled facts + fenced raw output per §3.5.
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: 'text',
|
|
114
|
+
text: `RESTForge package installed successfully.
|
|
115
|
+
|
|
116
|
+
Project path: ${projectCwd}
|
|
117
|
+
Installed version: @restforgejs/platform@${version}
|
|
118
|
+
Install location: node_modules/@restforgejs/platform
|
|
119
|
+
|
|
120
|
+
--- npm output ---
|
|
121
|
+
${result.stdout}
|
|
122
|
+
--- end npm output ---
|
|
123
|
+
|
|
124
|
+
For the assistant:
|
|
125
|
+
- Confirm to the user that the RESTForge package is installed in this project.
|
|
126
|
+
- Suggest the next step in plain words: generating the initial configuration skeleton (config and payload templates) so the project can be configured.
|
|
127
|
+
- Keep the reply concise. Do not paste the raw npm output unless the user explicitly asks. Do not mention internal tool names.`,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=install-package.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-package.js","sourceRoot":"","sources":["../../../src/tools/setup/install-package.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,uCAAuC;QAC9C,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4IA6ByH;QACtI,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,wEAAwE,CAAC;YACrF,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,OAAO,CAAC,MAAM,CAAC;iBACf,QAAQ,CAAC,sFAAsF,CAAC;SACpG;QACD,WAAW,EAAE;YACX,KAAK,EAAE,+BAA+B;YACtC,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,IAAI;SACrB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;QACzB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAEhC,qDAAqD;QACrD,oEAAoE;QACpE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;;;;;wJAK8H;qBAC3I;iBACF;gBACD,OAAO,EAAE,KAAK,EAAE,WAAW;aAC5B,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,KAAK,EACL,CAAC,SAAS,EAAE,yBAAyB,OAAO,EAAE,CAAC,EAC/C,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,CACtC,CAAC;QAEF,yDAAyD;QACzD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;qBACL,OAAO;WACjB,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;;;4FAM6E;qBAC/E;iBACF;gBACD,OAAO,EAAE,IAAI,EAAE,WAAW;aAC3B,CAAC;QACJ,CAAC;QAED,0EAA0E;QAC1E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;2CACiB,OAAO;;;;EAIhD,MAAM,CAAC,MAAM;;;;;;+HAMgH;iBACpH;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { readFile, access } from 'node:fs/promises';
|
|
3
|
+
import { resolve, join } from 'node:path';
|
|
4
|
+
import { parseEnvFile, isSensitiveKey, maskValue } from '../../lib/env-parser.js';
|
|
5
|
+
export function registerSetupReadEnv(server) {
|
|
6
|
+
server.registerTool('setup_read_env', {
|
|
7
|
+
title: 'Read Database Connection Env',
|
|
8
|
+
description: `Read and parse the config/db-connection.env file, returning all parameters as KEY=value lines. Sensitive fields (LICENSE, DB_PASSWORD, REDIS_PASSWORD, KAFKA_SASL_PASSWORD) are masked by default.
|
|
9
|
+
|
|
10
|
+
USE WHEN:
|
|
11
|
+
- The user asks to see the active/current configuration, parameters,
|
|
12
|
+
settings, or env values of a RESTForge project
|
|
13
|
+
- The user asks questions like "tampilkan parameter yang aktif",
|
|
14
|
+
"config apa yang sudah di-set", "show current settings", "cek konfigurasi",
|
|
15
|
+
"what's configured in this project"
|
|
16
|
+
- Verifying the current configuration before calling 'setup_write_env' or
|
|
17
|
+
'setup_update_env' to make changes
|
|
18
|
+
- Auditing the active config after a change
|
|
19
|
+
- Listing every parameter present in the file (including optional sections
|
|
20
|
+
like Live Sync, Redis, Kafka, Logging)
|
|
21
|
+
- Checking whether a RESTForge project has been set up at all (this tool
|
|
22
|
+
returns a clear "file not found" precondition if not)
|
|
23
|
+
|
|
24
|
+
DO NOT USE FOR:
|
|
25
|
+
- Writing values -> use 'setup_write_env' or 'setup_update_env'
|
|
26
|
+
- Validating connection -> use 'setup_validate_config'
|
|
27
|
+
|
|
28
|
+
This tool is READ-ONLY and safe to call repeatedly. Pass unmask=true to see real values of sensitive fields (use with care).
|
|
29
|
+
|
|
30
|
+
PRESENTATION GUIDANCE:
|
|
31
|
+
- Match the user's language. If the user writes in Indonesian, respond in Indonesian.
|
|
32
|
+
- Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "set up the initial config", "fill in the credentials", "update a single value", "validate the connection").
|
|
33
|
+
- Speak in plain language. Summarise the result; do not paste the full KEY=value list unless the user explicitly asks for it.
|
|
34
|
+
- Even when unmask=true, do not echo sensitive values (license keys, passwords) into chat unless the user explicitly asks. Prefer to confirm presence and length only.
|
|
35
|
+
- When a precondition is not met (e.g. config file is missing), frame it as a question or next-step suggestion rather than an error.`,
|
|
36
|
+
inputSchema: {
|
|
37
|
+
cwd: z.string().min(1).describe('Absolute path of the project folder'),
|
|
38
|
+
configFile: z
|
|
39
|
+
.string()
|
|
40
|
+
.default('db-connection.env')
|
|
41
|
+
.describe('Config file name in the config/ folder. Default: db-connection.env'),
|
|
42
|
+
unmask: z
|
|
43
|
+
.boolean()
|
|
44
|
+
.default(false)
|
|
45
|
+
.describe('When true, show real values of sensitive fields (LICENSE, *_PASSWORD). Default: false'),
|
|
46
|
+
},
|
|
47
|
+
annotations: {
|
|
48
|
+
title: 'Read Env Config',
|
|
49
|
+
readOnlyHint: true,
|
|
50
|
+
idempotentHint: true,
|
|
51
|
+
},
|
|
52
|
+
}, async ({ cwd, configFile, unmask }) => {
|
|
53
|
+
const projectCwd = resolve(cwd);
|
|
54
|
+
const envPath = join(projectCwd, 'config', configFile);
|
|
55
|
+
// Precondition check: the config file must exist before it can be read.
|
|
56
|
+
// Treated as a non-error precondition per the authoring guide §3.4.
|
|
57
|
+
try {
|
|
58
|
+
await access(envPath);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return {
|
|
62
|
+
content: [
|
|
63
|
+
{
|
|
64
|
+
type: 'text',
|
|
65
|
+
text: `Precondition not met: the configuration file does not exist yet.
|
|
66
|
+
|
|
67
|
+
Project path: ${projectCwd}
|
|
68
|
+
Expected file: ${envPath}
|
|
69
|
+
|
|
70
|
+
For the assistant:
|
|
71
|
+
- The user is trying to read a configuration that has not been created yet.
|
|
72
|
+
- Suggest generating the initial RESTForge configuration first, then retry reading it.
|
|
73
|
+
- When explaining to the user, say something like "the configuration file isn't there yet — should I set up the initial config first?". Do not mention internal tool names.`,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
isError: false,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Real I/O failure: surface as error per §3.4.
|
|
80
|
+
let content;
|
|
81
|
+
try {
|
|
82
|
+
content = await readFile(envPath, 'utf-8');
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
86
|
+
return {
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: 'text',
|
|
90
|
+
text: `Failed to read the configuration file.
|
|
91
|
+
|
|
92
|
+
Project path: ${projectCwd}
|
|
93
|
+
File: ${envPath}
|
|
94
|
+
Reason: ${msg}
|
|
95
|
+
|
|
96
|
+
For the assistant:
|
|
97
|
+
- Tell the user that the configuration file exists but could not be read.
|
|
98
|
+
- Summarise the likely cause (permissions, file lock, encoding) in plain language; do not paste the raw error unless the user explicitly asks.
|
|
99
|
+
- Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
isError: true,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const entries = parseEnvFile(content);
|
|
106
|
+
const kvEntries = entries.filter((e) => e.kind === 'kv');
|
|
107
|
+
// Success: one-line summary + labeled facts + fenced parameter block per §3.5.
|
|
108
|
+
const paramLines = [];
|
|
109
|
+
for (const entry of kvEntries) {
|
|
110
|
+
const displayValue = !unmask && isSensitiveKey(entry.key) ? maskValue(entry.value) : entry.value;
|
|
111
|
+
paramLines.push(`${entry.key}=${displayValue}`);
|
|
112
|
+
}
|
|
113
|
+
const sensitiveNote = unmask
|
|
114
|
+
? 'Sensitive fields: UNMASKED (real values present in the parameter block below).'
|
|
115
|
+
: 'Sensitive fields masked: LICENSE, DB_PASSWORD, REDIS_PASSWORD, KAFKA_SASL_PASSWORD.';
|
|
116
|
+
const text = `Configuration file read successfully.
|
|
117
|
+
|
|
118
|
+
Project path: ${projectCwd}
|
|
119
|
+
File: ${envPath}
|
|
120
|
+
Total parameters: ${kvEntries.length}
|
|
121
|
+
${sensitiveNote}
|
|
122
|
+
|
|
123
|
+
--- Parameters ---
|
|
124
|
+
${paramLines.join('\n')}
|
|
125
|
+
--- end Parameters ---
|
|
126
|
+
|
|
127
|
+
For the assistant:
|
|
128
|
+
- Confirm to the user that the configuration was read successfully.
|
|
129
|
+
- Summarise in plain language: how many parameters are set, and which key sections appear to be configured (e.g. database, license, optional Redis/Kafka/Live Sync).
|
|
130
|
+
- Do not paste the full parameter block unless the user explicitly asks to see every value.
|
|
131
|
+
- ${unmask
|
|
132
|
+
? 'Sensitive values are unmasked in the parameter block. Do NOT echo license keys or passwords into chat. Only confirm their presence (or length) unless the user explicitly asks for the literal value.'
|
|
133
|
+
: 'Sensitive values are masked. If the user wants to verify a real value, suggest re-running with the unmask option enabled.'}
|
|
134
|
+
- Do not mention internal tool names.`;
|
|
135
|
+
return { content: [{ type: 'text', text }] };
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=read-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-env.js","sourceRoot":"","sources":["../../../src/tools/setup/read-env.ts"],"names":[],"mappings":"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"}
|