jui-tools-mcp-server 2.12.8 → 2.12.10

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.
@@ -3772,14 +3772,14 @@
3772
3772
  },
3773
3773
  "keyboardAvoidance": {
3774
3774
  "type": "boolean",
3775
- "description": "Enable keyboard avoidance (default true). iOS: AdvancedKeyboardAvoidingScrollView with the configuration disabled when false. Android: imePadding() and the keyboardAvoidancePadding clearance are emitted only when not false. Declared swift-only from the initial commit while the kjui codegen had read it all along (2026-09-22).",
3775
+ "description": "Enable keyboard avoidance (default true). iOS: AdvancedKeyboardAvoidingScrollView with the configuration disabled when false. Android: KotlinJsonUI's Modifier.keyboardAvoidance (imePadding, the keyboardAvoidancePadding clearance, and scrolling the focused field up once the IME is up) is applied only when not false; both the codegen emit and the dynamic ScrollView call it. Declared swift-only from the initial commit while the kjui codegen had read it all along (2026-09-22).",
3776
3776
  "platform": ["swift", "kotlin"]
3777
3777
  },
3778
3778
  "keyboardAvoidancePadding": {
3779
3779
  "type": "number",
3780
3780
  "platform": ["swift", "kotlin"],
3781
3781
  "default": 20,
3782
- "description": "Clearance, in points/dp, that a focused text field keeps from the ScrollView's VISIBLE bottom edge while the soft keyboard is up. The edge is whatever bounds the scroll area at that moment: the top of a fixed footer laid out below the ScrollView, or the keyboard itself when the ScrollView meets it directly. Default 20 (the platform keyboard-avoidance default; absent means 20, not 0). iOS: KeyboardAvoidanceConfiguration.additionalPadding, applied as a bottom safe-area inset while the keyboard is visible. Android: bottom padding on the scrollable after imePadding() while the IME is visible, so bringIntoView stops that far above it. Ignored when keyboardAvoidance is false. Web: not applicable (no soft-keyboard avoidance in the web renderer)."
3782
+ "description": "Clearance, in points/dp, that a focused text field keeps from the ScrollView's VISIBLE bottom edge while the soft keyboard is up. The edge is whatever bounds the scroll area at that moment: the top of a fixed footer laid out below the ScrollView, or the keyboard itself when the ScrollView meets it directly. Default 20 (the platform keyboard-avoidance default; absent means 20, not 0). iOS: KeyboardAvoidanceConfiguration.additionalPadding, applied as a bottom safe-area inset while the keyboard is visible. Android: Modifier.keyboardAvoidance ends the scrollable's viewport that far above the IME while it is visible and scrolls the focused field to the viewport's edge once the IME is up (until 2.37.0 the follow was left to Compose's built-in tracking, which a device measured not doing it, 2026-09-22). Ignored when keyboardAvoidance is false. Web: not applicable (no soft-keyboard avoidance in the web renderer)."
3783
3783
  },
3784
3784
  "scrollBehavior": {
3785
3785
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jui-tools-mcp-server",
3
- "version": "2.12.8",
3
+ "version": "2.12.10",
4
4
  "description": "MCP server for JsonUI project management - wraps jui and jsonui-doc CLIs plus component spec lookup",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -44,7 +44,7 @@ const DATA_DIR = join(PROJECT_ROOT, "data");
44
44
  // 3. `npm run fetch-definitions` and commit the data/ diff together with
45
45
  // this pin in one commit
46
46
  // JSONUI_CLI_RAW_BASE still overrides the whole base URL for manual testing.
47
- const JSONUI_CLI_TAG = "v1.8.109";
47
+ const JSONUI_CLI_TAG = "v1.8.110";
48
48
  const BASE_URL =
49
49
  process.env.JSONUI_CLI_RAW_BASE ||
50
50
  `https://raw.githubusercontent.com/Tai-Kimura/jsonui-cli/${JSONUI_CLI_TAG}`;
@@ -14,9 +14,15 @@ export function register(server: McpServer, config: ServerConfig) {
14
14
  attributes: z.string().optional().describe("Attributes in key:type format (e.g., 'prop1:String,prop2:Int')"),
15
15
  container: z.boolean().optional().describe("Mark as container component"),
16
16
  skip_existing: z.boolean().optional().describe(
17
- "Leave existing converter files untouched (no overwrite prompt). " +
18
- "`jui build` enables this automatically; pass it here for idempotent " +
19
- "explicit scaffold runs."
17
+ "Leave existing converter and scaffold files untouched, without the " +
18
+ "overwrite prompt — for idempotent scaffold runs. Wins over `force` " +
19
+ "when both are set."
20
+ ),
21
+ force: z.boolean().optional().describe(
22
+ "Replace existing converter and scaffold files without the overwrite " +
23
+ "prompt. The scaffolds are the project's own code: edits made in them " +
24
+ "are lost. Needs jsonui-cli 1.8.113 or later (earlier `jui` rejects " +
25
+ "--force)."
20
26
  ),
21
27
  project_dir: z.string().optional().describe("Project directory (overrides JUI_PROJECT_DIR env)"),
22
28
  },
@@ -30,6 +36,7 @@ export function register(server: McpServer, config: ServerConfig) {
30
36
  if (params.attributes) { args.push("--attributes", params.attributes); }
31
37
  if (params.container) { args.push("--container"); }
32
38
  if (params.skip_existing) { args.push("--skip-existing"); }
39
+ if (params.force) { args.push("--force"); }
33
40
 
34
41
  const result = await runCli("jui", args, { cwd: projectDir });
35
42
  return { content: [{ type: "text", text: formatResult(result) }] };
@@ -284,6 +284,28 @@ describe("jui_generate_converter", () => {
284
284
  "--all",
285
285
  ]);
286
286
  });
287
+
288
+ // `jui g converter --force` exists from jsonui-cli 1.8.113; the tool had no
289
+ // way to pass it.
290
+ it("passes --force only when asked", async () => {
291
+ await harness.call("jui_generate_converter", {
292
+ all: true,
293
+ force: true,
294
+ project_dir: projectDir,
295
+ });
296
+ await harness.call("jui_generate_converter", { all: true, project_dir: projectDir });
297
+ expect(recorded[0].args).toEqual(["generate", "converter", "--all", "--force"]);
298
+ expect(recorded[1].args).toEqual(["generate", "converter", "--all"]);
299
+ });
300
+
301
+ // The description said "`jui build` enables this automatically": the build
302
+ // has not generated converters for a long time (jsonui-cli 1.8.113 removed
303
+ // the same sentence from its own docstring).
304
+ it("does not tell the agent that jui build skips existing converters", () => {
305
+ const schema = harness.tools.get("jui_generate_converter")!.schema;
306
+ expect(schema.skip_existing.description).not.toContain("jui build");
307
+ expect(schema.force.description).toContain("1.8.113");
308
+ });
287
309
  });
288
310
 
289
311
  describe("jui_verify", () => {