jui-tools-mcp-server 2.5.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.
Files changed (172) hide show
  1. package/.github/workflows/test.yml +35 -0
  2. package/README.md +148 -0
  3. package/data/attribute_definitions.json +4248 -0
  4. package/data/attribute_semantics.json +137 -0
  5. package/data/binding_semantics.json +115 -0
  6. package/data/component_metadata.json +769 -0
  7. package/data/coverage.json +114 -0
  8. package/data/screen_identity.json +350 -0
  9. package/dist/cli_runner.d.ts +10 -0
  10. package/dist/cli_runner.js +33 -0
  11. package/dist/config.d.ts +19 -0
  12. package/dist/config.js +67 -0
  13. package/dist/data/component_metadata.d.ts +30 -0
  14. package/dist/data/component_metadata.js +498 -0
  15. package/dist/data/derived.d.ts +198 -0
  16. package/dist/data/derived.js +293 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +130 -0
  19. package/dist/spec_loader.d.ts +110 -0
  20. package/dist/spec_loader.js +445 -0
  21. package/dist/tools/api/list_api_models.d.ts +10 -0
  22. package/dist/tools/api/list_api_models.js +37 -0
  23. package/dist/tools/api/list_api_specs.d.ts +19 -0
  24. package/dist/tools/api/list_api_specs.js +42 -0
  25. package/dist/tools/api/preview_api_model_sync.d.ts +11 -0
  26. package/dist/tools/api/preview_api_model_sync.js +34 -0
  27. package/dist/tools/context/get_project_config.d.ts +3 -0
  28. package/dist/tools/context/get_project_config.js +20 -0
  29. package/dist/tools/context/list_component_specs.d.ts +3 -0
  30. package/dist/tools/context/list_component_specs.js +35 -0
  31. package/dist/tools/context/list_layouts.d.ts +3 -0
  32. package/dist/tools/context/list_layouts.js +118 -0
  33. package/dist/tools/context/list_screen_specs.d.ts +3 -0
  34. package/dist/tools/context/list_screen_specs.js +37 -0
  35. package/dist/tools/context/read_layout_file.d.ts +3 -0
  36. package/dist/tools/context/read_layout_file.js +25 -0
  37. package/dist/tools/context/read_spec_file.d.ts +3 -0
  38. package/dist/tools/context/read_spec_file.js +27 -0
  39. package/dist/tools/doc/doc_generate_component.d.ts +3 -0
  40. package/dist/tools/doc/doc_generate_component.js +38 -0
  41. package/dist/tools/doc/doc_generate_html.d.ts +3 -0
  42. package/dist/tools/doc/doc_generate_html.js +46 -0
  43. package/dist/tools/doc/doc_generate_spec.d.ts +3 -0
  44. package/dist/tools/doc/doc_generate_spec.js +38 -0
  45. package/dist/tools/doc/doc_init_component.d.ts +3 -0
  46. package/dist/tools/doc/doc_init_component.js +30 -0
  47. package/dist/tools/doc/doc_init_spec.d.ts +3 -0
  48. package/dist/tools/doc/doc_init_spec.js +33 -0
  49. package/dist/tools/doc/doc_rules_init.d.ts +3 -0
  50. package/dist/tools/doc/doc_rules_init.js +25 -0
  51. package/dist/tools/doc/doc_rules_show.d.ts +3 -0
  52. package/dist/tools/doc/doc_rules_show.js +21 -0
  53. package/dist/tools/doc/doc_validate_component.d.ts +3 -0
  54. package/dist/tools/doc/doc_validate_component.js +39 -0
  55. package/dist/tools/doc/doc_validate_spec.d.ts +3 -0
  56. package/dist/tools/doc/doc_validate_spec.js +40 -0
  57. package/dist/tools/jui/jui_build.d.ts +3 -0
  58. package/dist/tools/jui/jui_build.js +31 -0
  59. package/dist/tools/jui/jui_generate_converter.d.ts +3 -0
  60. package/dist/tools/jui/jui_generate_converter.js +43 -0
  61. package/dist/tools/jui/jui_generate_project.d.ts +3 -0
  62. package/dist/tools/jui/jui_generate_project.js +43 -0
  63. package/dist/tools/jui/jui_generate_screen.d.ts +3 -0
  64. package/dist/tools/jui/jui_generate_screen.js +22 -0
  65. package/dist/tools/jui/jui_init.d.ts +3 -0
  66. package/dist/tools/jui/jui_init.js +42 -0
  67. package/dist/tools/jui/jui_migrate_layouts.d.ts +3 -0
  68. package/dist/tools/jui/jui_migrate_layouts.js +25 -0
  69. package/dist/tools/jui/jui_sync_tool.d.ts +3 -0
  70. package/dist/tools/jui/jui_sync_tool.js +33 -0
  71. package/dist/tools/jui/jui_verify.d.ts +3 -0
  72. package/dist/tools/jui/jui_verify.js +43 -0
  73. package/dist/tools/spec/get_binding_rules.d.ts +3 -0
  74. package/dist/tools/spec/get_binding_rules.js +8 -0
  75. package/dist/tools/spec/get_data_source.d.ts +3 -0
  76. package/dist/tools/spec/get_data_source.js +41 -0
  77. package/dist/tools/spec/get_modifier_order.d.ts +3 -0
  78. package/dist/tools/spec/get_modifier_order.js +14 -0
  79. package/dist/tools/spec/get_platform_mapping.d.ts +3 -0
  80. package/dist/tools/spec/get_platform_mapping.js +20 -0
  81. package/dist/tools/spec/get_screen_identity.d.ts +3 -0
  82. package/dist/tools/spec/get_screen_identity.js +22 -0
  83. package/dist/tools/spec/lookup_attribute.d.ts +3 -0
  84. package/dist/tools/spec/lookup_attribute.js +14 -0
  85. package/dist/tools/spec/lookup_component.d.ts +3 -0
  86. package/dist/tools/spec/lookup_component.js +15 -0
  87. package/dist/tools/spec/search_components.d.ts +3 -0
  88. package/dist/tools/spec/search_components.js +14 -0
  89. package/dist/tools/test/test_artifacts_pull.d.ts +3 -0
  90. package/dist/tools/test/test_artifacts_pull.js +48 -0
  91. package/dist/tools/test/test_artifacts_status.d.ts +3 -0
  92. package/dist/tools/test/test_artifacts_status.js +28 -0
  93. package/dist/tools/test/test_generate_description.d.ts +3 -0
  94. package/dist/tools/test/test_generate_description.js +27 -0
  95. package/dist/tools/test/test_generate_flow.d.ts +3 -0
  96. package/dist/tools/test/test_generate_flow.js +29 -0
  97. package/dist/tools/test/test_generate_screen.d.ts +3 -0
  98. package/dist/tools/test/test_generate_screen.js +29 -0
  99. package/dist/tools/test/test_mock_generate.d.ts +3 -0
  100. package/dist/tools/test/test_mock_generate.js +64 -0
  101. package/dist/tools/test/test_report.d.ts +3 -0
  102. package/dist/tools/test/test_report.js +26 -0
  103. package/dist/tools/test/test_validate.d.ts +3 -0
  104. package/dist/tools/test/test_validate.js +43 -0
  105. package/docs/design.md +227 -0
  106. package/install.sh +90 -0
  107. package/package.json +24 -0
  108. package/scripts/fetch-definitions.js +101 -0
  109. package/scripts/fetch-manifest.js +60 -0
  110. package/src/cli_runner.ts +55 -0
  111. package/src/config.ts +88 -0
  112. package/src/data/derived.ts +305 -0
  113. package/src/index.ts +157 -0
  114. package/src/spec_loader.ts +591 -0
  115. package/src/tools/api/list_api_models.ts +44 -0
  116. package/src/tools/api/list_api_specs.ts +53 -0
  117. package/src/tools/api/preview_api_model_sync.ts +41 -0
  118. package/src/tools/context/get_project_config.ts +27 -0
  119. package/src/tools/context/list_component_specs.ts +44 -0
  120. package/src/tools/context/list_layouts.ts +131 -0
  121. package/src/tools/context/list_screen_specs.ts +46 -0
  122. package/src/tools/context/read_layout_file.ts +35 -0
  123. package/src/tools/context/read_spec_file.ts +38 -0
  124. package/src/tools/doc/doc_generate_component.ts +43 -0
  125. package/src/tools/doc/doc_generate_html.ts +40 -0
  126. package/src/tools/doc/doc_generate_spec.ts +43 -0
  127. package/src/tools/doc/doc_init_component.ts +32 -0
  128. package/src/tools/doc/doc_init_spec.ts +37 -0
  129. package/src/tools/doc/doc_rules_init.ts +29 -0
  130. package/src/tools/doc/doc_rules_show.ts +27 -0
  131. package/src/tools/doc/doc_validate_component.ts +47 -0
  132. package/src/tools/doc/doc_validate_spec.ts +48 -0
  133. package/src/tools/jui/jui_build.ts +31 -0
  134. package/src/tools/jui/jui_generate_converter.ts +41 -0
  135. package/src/tools/jui/jui_generate_project.ts +37 -0
  136. package/src/tools/jui/jui_generate_screen.ts +28 -0
  137. package/src/tools/jui/jui_init.ts +38 -0
  138. package/src/tools/jui/jui_migrate_layouts.ts +29 -0
  139. package/src/tools/jui/jui_sync_tool.ts +33 -0
  140. package/src/tools/jui/jui_verify.ts +43 -0
  141. package/src/tools/spec/get_binding_rules.ts +16 -0
  142. package/src/tools/spec/get_data_source.ts +53 -0
  143. package/src/tools/spec/get_modifier_order.ts +22 -0
  144. package/src/tools/spec/get_platform_mapping.ts +28 -0
  145. package/src/tools/spec/get_screen_identity.ts +31 -0
  146. package/src/tools/spec/lookup_attribute.ts +22 -0
  147. package/src/tools/spec/lookup_component.ts +23 -0
  148. package/src/tools/spec/search_components.ts +22 -0
  149. package/src/tools/test/test_artifacts_pull.ts +47 -0
  150. package/src/tools/test/test_artifacts_status.ts +34 -0
  151. package/src/tools/test/test_generate_description.ts +33 -0
  152. package/src/tools/test/test_generate_flow.ts +33 -0
  153. package/src/tools/test/test_generate_screen.ts +33 -0
  154. package/src/tools/test/test_mock_generate.ts +58 -0
  155. package/src/tools/test/test_report.ts +32 -0
  156. package/src/tools/test/test_validate.ts +43 -0
  157. package/tests/__snapshots__/derived.test.ts.snap +279 -0
  158. package/tests/bundled_snapshot.test.ts +155 -0
  159. package/tests/cli_runner.test.ts +120 -0
  160. package/tests/config.test.ts +212 -0
  161. package/tests/derived.test.ts +114 -0
  162. package/tests/helpers.ts +272 -0
  163. package/tests/setup.ts +27 -0
  164. package/tests/snapshot_completeness.test.ts +152 -0
  165. package/tests/spec_loader.test.ts +488 -0
  166. package/tests/tools_cli.test.ts +687 -0
  167. package/tests/tools_context.test.ts +274 -0
  168. package/tests/tools_spec.test.ts +225 -0
  169. package/tests/tools_test.test.ts +284 -0
  170. package/tsconfig.json +15 -0
  171. package/uninstall.sh +46 -0
  172. package/vitest.config.ts +15 -0
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Group F (jsonui-test CLI) tool wrappers. child_process is mocked — tests
3
+ * pin the exact CLI argv each tool builds and the output contract each tool
4
+ * returns. No real jsonui-test binary is ever invoked.
5
+ */
6
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
7
+
8
+ const execFileMock = vi.hoisted(() => vi.fn());
9
+ vi.mock("child_process", () => ({ execFile: execFileMock }));
10
+ vi.mock("node:child_process", () => ({ execFile: execFileMock }));
11
+
12
+ import { ServerConfig } from "../src/config.js";
13
+ // Group F
14
+ import { register as registerTestValidate } from "../src/tools/test/test_validate.js";
15
+ import { register as registerTestGenerateScreen } from "../src/tools/test/test_generate_screen.js";
16
+ import { register as registerTestGenerateFlow } from "../src/tools/test/test_generate_flow.js";
17
+ import { register as registerTestGenerateDescription } from "../src/tools/test/test_generate_description.js";
18
+ import { register as registerTestReport } from "../src/tools/test/test_report.js";
19
+ import { register as registerTestMockGenerate } from "../src/tools/test/test_mock_generate.js";
20
+ import { register as registerTestArtifactsPull } from "../src/tools/test/test_artifacts_pull.js";
21
+ import { register as registerTestArtifactsStatus } from "../src/tools/test/test_artifacts_status.js";
22
+
23
+ import {
24
+ cleanupTempDirs,
25
+ createToolHarness,
26
+ makeFixtureProject,
27
+ makeTempDir,
28
+ type ToolHarness,
29
+ } from "./helpers.js";
30
+
31
+ type ExecCallback = (error: any, stdout: string, stderr: string) => void;
32
+
33
+ interface RecordedCall {
34
+ command: string;
35
+ args: string[];
36
+ options: Record<string, any>;
37
+ }
38
+
39
+ let recorded: RecordedCall[];
40
+ let nextResponse: { error?: any; stdout?: string; stderr?: string };
41
+ let harness: ToolHarness;
42
+ let projectDir: string;
43
+
44
+ beforeEach(() => {
45
+ delete process.env.JUI_PROJECT_DIR;
46
+ recorded = [];
47
+ nextResponse = {};
48
+ execFileMock.mockReset();
49
+ execFileMock.mockImplementation(
50
+ (command: string, args: string[], options: any, callback: ExecCallback) => {
51
+ recorded.push({ command, args, options });
52
+ callback(
53
+ nextResponse.error ?? null,
54
+ nextResponse.stdout ?? "",
55
+ nextResponse.stderr ?? ""
56
+ );
57
+ }
58
+ );
59
+
60
+ projectDir = makeTempDir("project");
61
+ makeFixtureProject(projectDir);
62
+
63
+ harness = createToolHarness();
64
+ const config = new ServerConfig();
65
+ registerTestValidate(harness.server, config);
66
+ registerTestGenerateScreen(harness.server, config);
67
+ registerTestGenerateFlow(harness.server, config);
68
+ registerTestGenerateDescription(harness.server, config);
69
+ registerTestReport(harness.server, config);
70
+ registerTestMockGenerate(harness.server, config);
71
+ registerTestArtifactsPull(harness.server, config);
72
+ registerTestArtifactsStatus(harness.server, config);
73
+ });
74
+
75
+ afterEach(() => {
76
+ delete process.env.JUI_PROJECT_DIR;
77
+ cleanupTempDirs();
78
+ });
79
+
80
+ function failWithCode(code: number, stdout = "", stderr = ""): void {
81
+ nextResponse = {
82
+ error: Object.assign(new Error(`exit ${code}`), { code }),
83
+ stdout,
84
+ stderr,
85
+ };
86
+ }
87
+
88
+ describe("Group F registration", () => {
89
+ it("registers all 8 jsonui-test tools", () => {
90
+ expect([...harness.tools.keys()].sort()).toEqual(
91
+ [
92
+ "test_artifacts_pull",
93
+ "test_artifacts_status",
94
+ "test_generate_description",
95
+ "test_generate_flow",
96
+ "test_generate_screen",
97
+ "test_mock_generate",
98
+ "test_report",
99
+ "test_validate",
100
+ ].sort()
101
+ );
102
+ });
103
+ });
104
+
105
+ describe("test_validate", () => {
106
+ it("builds the base argv and runs in the project dir", async () => {
107
+ nextResponse = { stdout: "All valid" };
108
+ await harness.call("test_validate", {
109
+ project_dir: projectDir,
110
+ files: ["tests/screens"],
111
+ });
112
+ expect(recorded).toEqual([
113
+ expect.objectContaining({
114
+ command: "jsonui-test",
115
+ args: ["validate", "tests/screens"],
116
+ options: expect.objectContaining({ cwd: projectDir }),
117
+ }),
118
+ ]);
119
+ });
120
+
121
+ it("maps every optional flag, including no_install", async () => {
122
+ nextResponse = { stdout: "All valid" };
123
+ await harness.call("test_validate", {
124
+ project_dir: projectDir,
125
+ files: ["tests/screens", "login.test.json"],
126
+ verbose: true,
127
+ quiet: true,
128
+ no_mock_check: true,
129
+ no_install: true,
130
+ });
131
+ expect(recorded[0].args).toEqual([
132
+ "validate",
133
+ "tests/screens",
134
+ "login.test.json",
135
+ "--verbose",
136
+ "--quiet",
137
+ "--no-mock-check",
138
+ "--no-install",
139
+ ]);
140
+ });
141
+
142
+ it("omits --no-install when no_install is false or absent (CLI-default behavior)", async () => {
143
+ nextResponse = { stdout: "All valid" };
144
+ await harness.call("test_validate", {
145
+ project_dir: projectDir,
146
+ files: ["tests"],
147
+ no_install: false,
148
+ });
149
+ expect(recorded[0].args).toEqual(["validate", "tests"]);
150
+ });
151
+ });
152
+
153
+ describe("test_artifacts_pull", () => {
154
+ it("accepts platform web and maps it to --platform web", async () => {
155
+ nextResponse = { stdout: '{"outputDir":"/p","files":[],"skipped":[]}' };
156
+ await harness.call("test_artifacts_pull", {
157
+ project_dir: projectDir,
158
+ platform: "web",
159
+ });
160
+ expect(recorded[0].args).toEqual([
161
+ "artifacts",
162
+ "pull",
163
+ "--json",
164
+ "--platform",
165
+ "web",
166
+ ]);
167
+ });
168
+
169
+ it("builds the full argv, runs in the project dir with a 180s timeout, and passes JSON stdout through verbatim", async () => {
170
+ const payload =
171
+ '{"outputDir":"/p/tests/artifacts","files":["/p/a.png"],"skipped":[]}';
172
+ nextResponse = { stdout: payload };
173
+ const text = await harness.call("test_artifacts_pull", {
174
+ project_dir: projectDir,
175
+ platform: "ios",
176
+ xcresult: "/x/y.xcresult",
177
+ clean: true,
178
+ });
179
+ expect(recorded).toEqual([
180
+ expect.objectContaining({
181
+ command: "jsonui-test",
182
+ args: [
183
+ "artifacts",
184
+ "pull",
185
+ "--json",
186
+ "--platform",
187
+ "ios",
188
+ "--xcresult",
189
+ "/x/y.xcresult",
190
+ "--clean",
191
+ ],
192
+ options: expect.objectContaining({ cwd: projectDir, timeout: 180_000 }),
193
+ }),
194
+ ]);
195
+ expect(text).toBe(payload);
196
+ // The CLI JSON survives untouched — no wrapper envelope.
197
+ expect(JSON.parse(text)).toEqual({
198
+ outputDir: "/p/tests/artifacts",
199
+ files: ["/p/a.png"],
200
+ skipped: [],
201
+ });
202
+ });
203
+
204
+ it("maps the serial flag (Android)", async () => {
205
+ nextResponse = { stdout: "{}" };
206
+ await harness.call("test_artifacts_pull", {
207
+ project_dir: projectDir,
208
+ platform: "android",
209
+ serial: "emulator-5554",
210
+ });
211
+ expect(recorded[0].args).toEqual([
212
+ "artifacts",
213
+ "pull",
214
+ "--json",
215
+ "--platform",
216
+ "android",
217
+ "--serial",
218
+ "emulator-5554",
219
+ ]);
220
+ });
221
+
222
+ it("reports CLI failure via the formatResult contract", async () => {
223
+ failWithCode(1, "partial log", "no xcresult found");
224
+ const parsed = JSON.parse(
225
+ await harness.call("test_artifacts_pull", { project_dir: projectDir })
226
+ );
227
+ expect(parsed).toEqual({
228
+ success: false,
229
+ output: "partial log",
230
+ errors: "no xcresult found",
231
+ });
232
+ });
233
+
234
+ it("falls back to formatResult when exit-0 stdout is not JSON", async () => {
235
+ nextResponse = { stdout: "pulled 3 artifacts" };
236
+ const parsed = JSON.parse(
237
+ await harness.call("test_artifacts_pull", { project_dir: projectDir })
238
+ );
239
+ expect(parsed).toEqual({ success: true, output: "pulled 3 artifacts" });
240
+ });
241
+
242
+ it("does not spawn anything when no project dir is configured", async () => {
243
+ const text = await harness.call("test_artifacts_pull");
244
+ expect(text).toMatch(/^Error: /);
245
+ expect(execFileMock).not.toHaveBeenCalled();
246
+ });
247
+ });
248
+
249
+ describe("test_artifacts_status", () => {
250
+ it("runs `jsonui-test artifacts status --json` and passes JSON stdout through verbatim", async () => {
251
+ const payload =
252
+ '{"outputDir":"/p/tests/artifacts","ios":{"xcresult":"latest"},"android":{"appId":"com.example"},"files":[]}';
253
+ nextResponse = { stdout: `${payload}\n` };
254
+ const text = await harness.call("test_artifacts_status", {
255
+ project_dir: projectDir,
256
+ });
257
+ expect(recorded).toEqual([
258
+ expect.objectContaining({
259
+ command: "jsonui-test",
260
+ args: ["artifacts", "status", "--json"],
261
+ options: expect.objectContaining({ cwd: projectDir }),
262
+ }),
263
+ ]);
264
+ expect(text).toBe(payload);
265
+ });
266
+
267
+ it("reports CLI failure via the formatResult contract", async () => {
268
+ failWithCode(2, "", "artifacts not configured");
269
+ const parsed = JSON.parse(
270
+ await harness.call("test_artifacts_status", { project_dir: projectDir })
271
+ );
272
+ expect(parsed).toEqual({
273
+ success: false,
274
+ output: "",
275
+ errors: "artifacts not configured",
276
+ });
277
+ });
278
+
279
+ it("does not spawn anything when no project dir is configured", async () => {
280
+ const text = await harness.call("test_artifacts_status");
281
+ expect(text).toMatch(/^Error: /);
282
+ expect(execFileMock).not.toHaveBeenCalled();
283
+ });
284
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "resolveJsonModule": true,
11
+ "declaration": true,
12
+ "skipLibCheck": true
13
+ },
14
+ "include": ["src/**/*"]
15
+ }
package/uninstall.sh ADDED
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ INSTALL_DIR="$HOME/.jsonui-mcp-server"
5
+ CLAUDE_JSON="$HOME/.claude.json"
6
+
7
+ echo "=== JUI Tools MCP Server Uninstaller ==="
8
+
9
+ # 1. Remove from ~/.claude.json
10
+ if [ -f "$CLAUDE_JSON" ]; then
11
+ node -e "
12
+ const fs = require('fs');
13
+ const data = JSON.parse(fs.readFileSync('$CLAUDE_JSON', 'utf8'));
14
+ let removed = false;
15
+ if (data.mcpServers) {
16
+ if (data.mcpServers['jui-tools']) {
17
+ delete data.mcpServers['jui-tools'];
18
+ removed = true;
19
+ }
20
+ if (data.mcpServers['jsonui-spec']) {
21
+ delete data.mcpServers['jsonui-spec'];
22
+ removed = true;
23
+ }
24
+ }
25
+ if (removed) {
26
+ fs.writeFileSync('$CLAUDE_JSON', JSON.stringify(data, null, 2));
27
+ console.log('Removed MCP server entries from Claude Code config.');
28
+ } else {
29
+ console.log('No MCP server entries found in config.');
30
+ }
31
+ "
32
+ else
33
+ echo "Config file not found: $CLAUDE_JSON"
34
+ fi
35
+
36
+ # 2. Remove installed files
37
+ if [ -d "$INSTALL_DIR" ]; then
38
+ echo "Removing $INSTALL_DIR..."
39
+ rm -rf "$INSTALL_DIR"
40
+ echo "Removed installation directory."
41
+ else
42
+ echo "Installation directory not found: $INSTALL_DIR"
43
+ fi
44
+
45
+ echo ""
46
+ echo "Uninstall complete. Restart Claude Code to apply."
@@ -0,0 +1,15 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ["tests/**/*.test.ts"],
6
+ // Tests use process.chdir() to control the "cwd" fallback layer of the
7
+ // SpecLoader, which is unavailable in worker threads — force child
8
+ // process isolation.
9
+ pool: "forks",
10
+ // Hermeticity guard: strip environment leakage from the developer's real
11
+ // machine (a real ~/.jsonui-cli install, JSONUI_CLI_PATH, JUI_PROJECT_DIR)
12
+ // before any test module is imported.
13
+ setupFiles: ["tests/setup.ts"],
14
+ },
15
+ });