feat(schematic): expose justify directive on field labels via MCP
Add optional `justify` property to `fieldPositions` entries in `edit_schematic_component` and to `set_schematic_component_property`. Changes: - `python/kicad_interface.py`: new `_set_justify_on_property()` helper that adds/replaces/removes the `(justify ...)` token inside a property's `(effects ...)` block. Passing "center" (the KiCad default) removes the directive entirely. Integrated into `_set_property_in_block()` (for the `properties` dict path) and into the `field_positions` loop in `_handle_edit_schematic_component()`. `_handle_set_schematic_component_property()` now forwards `justify` from params through to the spec dict. Also fixes pre-existing mypy type-ignore on `circle.radius` (kipy stub). - `src/tools/schematic.ts`: extend the `fieldPositions` Zod schema to accept `justify?: string | string[]` (array form normalised to a space-separated string before the Python call). Add `justify?: string` to `set_schematic_component_property`. - `python/commands/routing.py`: fix pre-existing mypy error — annotate `ex` and `ey` as `float` in `_point_to_segment_distance_nm`. - `python/commands/pin_locator.py`: fix pre-existing mypy error — use explicit `str()` cast on `pin_data["number"]` before `dict.get()` call. - `tests/test_schematic_field_justify.py`: 14 unit + integration tests covering add/replace/remove of the justify directive and backward compatibility (calls without justify leave existing directives untouched). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -188,11 +188,21 @@ use edit_component instead.`,
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
angle: z.number().optional().default(0),
|
||||
justify: z
|
||||
.union([z.string(), z.array(z.string())])
|
||||
.optional()
|
||||
.describe(
|
||||
'Text justification: "left", "right", "center", "top", "bottom", or combined ' +
|
||||
'"left top" / "right bottom". Array form ["left", "top"] is also accepted. ' +
|
||||
'Omit to leave the existing justify unchanged. Pass "center" to reset to ' +
|
||||
"the KiCad default (removes the justify directive).",
|
||||
),
|
||||
}),
|
||||
)
|
||||
.optional()
|
||||
.describe(
|
||||
'Reposition field labels: map of field name to {x, y, angle} (e.g. {"Reference": {"x": 12.5, "y": 17.0}})',
|
||||
"Reposition field labels: map of field name to {x, y, angle, justify?} " +
|
||||
'(e.g. {"Reference": {"x": 12.5, "y": 17.0, "justify": "left"}})',
|
||||
),
|
||||
properties: z
|
||||
.record(
|
||||
@@ -240,7 +250,10 @@ use edit_component instead.`,
|
||||
footprint?: string;
|
||||
value?: string;
|
||||
newReference?: string;
|
||||
fieldPositions?: Record<string, { x: number; y: number; angle?: number }>;
|
||||
fieldPositions?: Record<
|
||||
string,
|
||||
{ x: number; y: number; angle?: number; justify?: string | string[] }
|
||||
>;
|
||||
properties?: Record<
|
||||
string,
|
||||
| string
|
||||
@@ -255,6 +268,16 @@ use edit_component instead.`,
|
||||
>;
|
||||
removeProperties?: string[];
|
||||
}) => {
|
||||
// Normalise array-form justify (["left", "top"]) to the space-separated
|
||||
// string form ("left top") that the Python backend expects.
|
||||
if (args.fieldPositions) {
|
||||
for (const fieldName of Object.keys(args.fieldPositions)) {
|
||||
const pos = args.fieldPositions[fieldName];
|
||||
if (Array.isArray(pos.justify)) {
|
||||
pos.justify = (pos.justify as string[]).join(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
const result = await callKicadScript("edit_schematic_component", args);
|
||||
if (result.success) {
|
||||
const updated = result.updated ?? {};
|
||||
@@ -337,6 +360,14 @@ with the \`properties\` parameter instead.`,
|
||||
"Hide the property text on the schematic canvas. Defaults to true for newly-created custom properties.",
|
||||
),
|
||||
fontSize: z.number().optional().describe("Font size in mm for the label (default: 1.27)"),
|
||||
justify: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
'Text justification for the property label. KiCad alignment keywords: "left", "right", ' +
|
||||
'"center", "top", "bottom", or combined e.g. "left top". Omit to leave unchanged. ' +
|
||||
'Pass "center" to reset to the KiCad default.',
|
||||
),
|
||||
},
|
||||
async (args: {
|
||||
schematicPath: string;
|
||||
@@ -348,6 +379,7 @@ with the \`properties\` parameter instead.`,
|
||||
angle?: number;
|
||||
hide?: boolean;
|
||||
fontSize?: number;
|
||||
justify?: string;
|
||||
}) => {
|
||||
const result = await callKicadScript("set_schematic_component_property", args);
|
||||
if (result.success) {
|
||||
|
||||
Reference in New Issue
Block a user