fix: search_tools now includes direct tools (snapshot_project etc.)

- searchTools() previously only searched routed tool categories, so
  direct tools like snapshot_project, save_project, create_project
  returned 0 results when Claude called search_tools('snapshot')
- Direct tools are now searched first, with a hint that they must be
  called directly (not via execute_tool)

Also includes routing.py zone-inset fix for rounded board corners
(already staged from previous session)
This commit is contained in:
Tom
2026-03-07 09:56:08 +01:00
parent b6e1b8b7b1
commit 0f1bfa3eff
2 changed files with 30 additions and 8 deletions

View File

@@ -1095,11 +1095,25 @@ class RoutingCommands:
y1 = board_box.GetY() / scale y1 = board_box.GetY() / scale
x2 = (board_box.GetX() + board_box.GetWidth()) / scale x2 = (board_box.GetX() + board_box.GetWidth()) / scale
y2 = (board_box.GetY() + board_box.GetHeight()) / scale y2 = (board_box.GetY() + board_box.GetHeight()) / scale
# Detect corner radius from Edge.Cuts arcs so the zone rectangle
# stays inside the rounded board corners (avoids zone visually
# extending outside Edge.Cuts before refill)
corner_radius = 0.0
edge_layer_id = self.board.GetLayerID("Edge.Cuts")
for item in self.board.GetDrawings():
if item.GetLayer() == edge_layer_id and item.GetClass() == "PCB_ARC":
r = item.GetRadius() / scale
if r > corner_radius:
corner_radius = r
# Inset the zone rectangle by the corner radius so its corners
# lie on the straight portions of the board edge.
inset = corner_radius
points = [ points = [
{"x": x1, "y": y1}, {"x": x1 + inset, "y": y1 + inset},
{"x": x2, "y": y1}, {"x": x2 - inset, "y": y1 + inset},
{"x": x2, "y": y2}, {"x": x2 - inset, "y": y2 - inset},
{"x": x1, "y": y2}, {"x": x1 + inset, "y": y2 - inset},
] ]
else: else:
return { return {

View File

@@ -228,16 +228,24 @@ export function searchTools(query: string): SearchResult[] {
const q = query.toLowerCase(); const q = query.toLowerCase();
const matches: SearchResult[] = []; const matches: SearchResult[] = [];
// This is a placeholder - we'll populate descriptions from actual tool definitions // Search direct tools first
// For now, we'll search by name and category for (const toolName of directToolNames) {
if (toolName.toLowerCase().includes(q)) {
matches.push({
category: "direct",
tool: toolName,
description: `${toolName} (direct tool — call directly, no execute_tool needed)`
});
}
}
// Search routed tools by name and category
for (const category of toolCategories) { for (const category of toolCategories) {
// Check if category name or description matches
const categoryMatch = const categoryMatch =
category.name.toLowerCase().includes(q) || category.name.toLowerCase().includes(q) ||
category.description.toLowerCase().includes(q); category.description.toLowerCase().includes(q);
for (const toolName of category.tools) { for (const toolName of category.tools) {
// Check if tool name matches or category matches
if (toolName.toLowerCase().includes(q) || categoryMatch) { if (toolName.toLowerCase().includes(q) || categoryMatch) {
matches.push({ matches.push({
category: category.name, category: category.name,