Repository navigation
Conversation
* Write a board index file, and read it on the board list page (#74) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fall back to the directory listing when index.json is missing Data built before the board index has no pcbs/index.json. On a 404 the board list page now reads the nginx JSON directory listing, as before, instead of showing an error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Add an MCP server in Docker with a list_boards tool (#75) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix review findings on the MCP server - http.js: read the path without new URL(), which threw on a target such as "//[" and took the process down. Test added. - server.js: log tool errors that are not BoardError; the SDK turns them into tool errors and logs nothing. - nginx.conf: give the URI in proxy_pass, so //mcp reaches the server as /mcp. - main.js: let requests in progress finish on shutdown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* MCP tool locate: where parts are on the board, by refdes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * locate: say which way angle turns the rectangle Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* MCP tool net_places: every pad on a net, with refdes, side and position Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * net_places: trim the net name, explain a net with no pads Trim the net name like locate trims refdes. Say in the tool description that a net with no pads gives found: true and no pads. Note in pads.js that Allegro writes a through-hole pin as two pads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * pads.js: note that Allegro through-hole pins are listed twice Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * pads.js: merge an Allegro through-hole pin pair into one pad Allegro writes a through-hole pin as an F "th" pad and a B "smd" pad at the same position. boardPads now gives one "th" pad on both sides, and keeps pin1 if either pad has it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* MCP tool nearest: reachable pads on a net near a part or point Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * nearest: sort by distance only, mark own and covered_by pads instead of dropping Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * nearest: review fixes (own refdes never covers, ambiguous refdes error, covers after limit) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Pad names in the KiCad export, pin in net_places and nearest (#90) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * Review fixes: empty pad name in merges, stock-ibom wording A merged pad pair now takes the other half's name when one half has an empty name. The tool descriptions say that KiCad boards from stock ibom have no pin either. The fixture README warns that regenerating ciaa-acc adds names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* nearest: the near part's own pads do not count toward limit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * nearest: plain loop for the limit cut, no side effect in filter Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…resort (#97) Same input as nearest. Vias are zero-length tracks on two or more layers; copies at one point are one via. Reachable only from the outer layers a via is on. Vias under a part are kept and marked covered_by, as nearest does for pads. The description and every answer say vias are a last resort and are often under soldermask, which the export cannot tell. The near/side/cover logic shared with nearest moves to mcp/src/near.js. Closes #79 Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#98) * nearest_vias: vias covered by the near part do not count toward limit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * nearest_vias: vias inside the near part's box do not count toward limit A through via under a front BGA is free on the back and gets no covered_by, so keying on covered_by still let fan-out vias fill the list. Now any via inside the near part's footprint rectangle, on either side, does not count. Covers are looked up for the returned vias only again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* MCP tool link: build a viewer link from structured fields (#81) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * link: review round 1 fixes - Side: count the focused part's side whenever the viewer turns to it (no view, no zoom, and a marker or a given side), not with zoom. - A view that rounds to no width or height is an error. - A net or copper layer that matches two names when case is ignored says so, as refs do. One matchName in pads.js for all of them. - Net names and pad nets are built once, only when a net is asked for. - The same error line is not listed twice. - base_url and VIEWER_URL text: the board list page's address, not the viewer page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* MCP tool snapshot: PNG of what a viewer link shows (#82) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * snapshot: a late browser disconnect no longer drops a newer browser; apt in its own Docker layer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* MCP stdio mode: boards from a static site over HTTP (#83) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * Keep Chromium's sandbox outside Docker; share concurrent board fetches Chromium now keeps its sandbox unless CHROMIUM_NO_SANDBOX=1, which only the MCP Docker image sets. A sandbox that cannot start is a tool error that says so. httpStore shares one fetch between calls for the same file, and a 304 re-counts the entry's bytes and takes new validators. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* README: host boards on a static site (#84) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * README static site: copy for local test, soften .nojekyll note Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Show pad names in the viewer (#96) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * Pad name test matches the MCP tools padName() takes a pad name only when it is a string, as mcp/src/pads.js does, so the viewer and the tools agree on which pads have a pin name. Tooltip and pad table both use it. Fix the pad table comment: it does not match the tooltip for an unnamed pin-1 pad. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Agent skill for the viewer MCP tools (#14) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * Skill: fixes from review round 1 - Any snapshot error: give the link and say it was not checked. - Focus the pad's own part, not the near part; frame a via with a view. - A net with no pads: leave it out of nets and keep the via marker. - Through-hole side: trust the side field. - Look for the tools by name, not by server name. - A generic rail-name example instead of one board. - Vias are "often" covered, as the tool says; fix the list formatting. - README: the link is an alternative to the copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Pad table: head the first column "Pin", not "#" Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x * Pad table test: check the Pin header on an unnamed board too Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
|
/prr round 1 (code-review run on the whole epic). 10 findings, each checked against the code. To fix on
Need a decision (not fixed): FYI (not fixing): |
- pads.js: merge a TH pad pair only when both pads are on the same net, so an SMD pad on another net at the same point is no longer lost. - boards.js: a folder or an unreadable file in diskStore is a tool error, not an internal one. - locate.js: match refdes with footprintsByRef, as the other tools do. - render.js: put padLabel's comment back on padLabel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x
|
Decisions on the round 1 findings (user):
|
A board skipped as up to date keeps the title the old index.json gives it, so its payload is not read again. Built boards, boards missing from the old index and files not from the source are still read. A missing or unreadable old index falls back to reading every payload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x
|
/prr round 2 (code-review run on e1bf597 and 1448b4b, the commits after the round 1 comment). Fixed: finding 6 in 1448b4b, as decided. build_boards.py reuses the title from the old index.json for boards skipped as up to date. Built boards, boards missing from the old index, and files not from the source are still read. A missing or unreadable old index falls back to reading every payload. Tests in tests/browser/board-index.spec.js: skipped board keeps its title with a payload that is no JSON (fails on the old code), rebuilt board gets its new title, corrupt old index falls back. Review findings, all checked against the code. None fixed:
CI green on 1448b4b. Merging by squash, as decided. |
The agent MCP epic (#73), merged child by child into
agent-mcp. Each child PR had its own/prrreview.What it adds:
mcp/). It runs in Docker as a second service behind/mcp, or locally over stdio against a static site.list_boards,locate,net_places,nearest,nearest_vias,link,snapshot.build_boards.pywritespcbs/index.json; the board list page reads it.pinin the tools, and pin names in the viewer.mark=link key that draws a marker.skills/pcb-viewer/.Changes for running servers:
docker-compose.ymlhas a second service,pcb-mcp. SetVIEWER_URLto the address users open.ghcr.io/gherkin/htmlpcbviewer-mcp, about 592 MB (Chromium forsnapshot).Closes #73
Closes #74
Closes #75
Closes #76
Closes #77
Closes #78
Closes #79
Closes #80
Closes #81
Closes #82
Closes #83
Closes #84
Closes #87
Closes #90
Closes #96
Closes #14
🤖 Generated with Claude Code
https://claude.ai/code/session_01FzHC7LspikUyimHw5ptN8x