diff --git a/README.md b/README.md index 6a6ab1f5..b69e4866 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,69 @@ Python MCP server for SolidWorks automation with 154 tools, plus an optional age I took SolidWorks' own U-Joint sample, read every part, sketch, feature and mate, and wrote it up as a plain-English prompt: eight parts, a crank sub-assembly, and a main assembly that has to move like a real joint. Then Claude Code (Opus 5.5, medium effort) built it from that prompt alone. +
+Prompt + +> I want to build a small hand-cranked universal joint in SolidWorks: eight parts, a crank sub-assembly, and the main assembly. It's a mechanism: turning the knob turns the crank, which drives the joint through an angle, so the assemblies must still move the way described in sections 9 and 10. Please reason through each part before you start drawing, check every part once it's built, and tell me if something can't be done with the tools rather than guessing. All sizes are in millimetres (the original was drawn in inches, so the numbers are odd). SolidWorks' Y axis is up. Save every part and both assemblies in this folder, with the names given below. +> +> **1. bracket.SLDPRT: a bent plate, 6.35 mm thick and 38.1 mm wide.** +> Seen from the side (sketch on the Right plane, Y up, Z towards the front), the inside outline of the bend is an open chain: +> - a back wall going straight up 82.55 mm from the origin; +> - from its top, a top arm going forward 57.15 mm; +> - from the origin, a bottom foot going forward 44.45 mm; +> - from the front of the foot, a lip rising at 40° for 42.77 mm (it ends 27.49 mm up and 77.22 mm forward). +> The 6.35 mm thickness is on the outside of that outline: above the top arm, behind the back wall and under the foot. The 38.1 mm width is centred on the Right plane. Drill a 12.7 mm hole straight down through the top arm and on through the foot below it (one cut, both plates), centred across the width and 38.1 mm forward of the back wall's inside face. +> +> **2. Yoke_male.SLDPRT: a fork with a stub shaft.** +> - Start with a 38.1 mm diameter cylinder, 47.625 mm tall, standing on the Top plane. +> - Its bottom becomes a fork with two ears. Each ear is 19.05 mm wide and 8.89 mm thick, and the gap between them is 20.32 mm, centred. Each ear has a rounded end: a full radius of 9.525 mm, centred 9.525 mm above the bottom. Where an ear meets the solid part of the cylinder, round the shoulder with a 9.525 mm radius, so the solid part starts 29.21 mm above the bottom. +> - Drill a 9.525 mm cross hole through both ears at the centre of their rounded ends, square to the ears. +> - On top, add a 12.7 mm diameter stub, 19.05 mm tall, on the cylinder's axis. Chamfer its top edge 1.27 mm at 60°. +> - Cut a flat on the stub, 12.7 mm long down from its top. The flat is 4.7625 mm from the axis, so it is 1.5875 mm deep. +> +> **3. Yoke_female.SLDPRT:** the same 38.1 x 47.625 mm cylinder with the same fork and the same cross hole as the male yoke, but no stub. Instead, a 9.525 mm hole goes all the way through along its axis. +> +> **4. spider.SLDPRT:** a 19.05 mm cube centred on the origin. It has two 9.525 mm holes, both through its centre: one front to back, and one left to right. +> +> **5. pin.SLDPRT:** a 9.398 mm diameter rod, 38.1 mm long. +> +> **6. crank-shaft.SLDPRT: a 12.573 mm diameter shaft, 40 mm long, standing on the Top plane.** +> - Around its bottom 15.875 mm, a collar 18.923 mm in diameter. +> - A 4.763 mm fillet where the collar meets the shaft, and a 4.763 mm fillet on the collar's top outer edge. +> - In the bottom, a D-shaped socket 12.7 mm deep. It is a 12.954 mm circle with a flat 4.889 mm from the axis, to take the male yoke's stub. +> - A 2.381 mm cross hole through the collar wall, square to the socket's flat and 6.35 mm up from the bottom. +> - At the top, a matching flat 6.35 mm long, 4.889 mm from the axis. +> - A 0.794 mm x 45° chamfer on the top end. +> +> **7. crank-arm.SLDPRT: a flat bar, 75 x 19.05 x 6.35 mm.** +> - Near one end, a 12.7 mm D-hole centred 9.525 mm from the end and on the bar's centreline. Its flat is 4.889 mm from the hole's centre, towards that end. It fits the shaft's top flat. +> - Near the other end, a 4.763 mm hole 9.525 mm from that end, also on the centreline. +> +> **8. crank-knob.SLDPRT: a mushroom-shaped knob, revolved 360° about the vertical axis.** Going up from the bottom, its profile has: +> - a 4.572 mm diameter shank, 6.35 mm long; +> - a step out to a 9.525 mm diameter; +> - a concave quarter-round of radius 6.35 mm that flares out to 22.225 mm diameter, 12.7 mm up; +> - a convex half-round of radius 4.7625 mm that reaches 31.75 mm diameter at its widest; +> - a flat top 22.225 mm in diameter, 22.225 mm above the bottom. +> +> **9. crank sub.SLDASM:** +> - The crank shaft is fixed. +> - The crank arm's D-hole goes on the shaft's top flat: the hole is concentric with the shaft, the flats are parallel, and the arm sits on the shoulder where the flat starts. The flats lock the arm to the shaft, so they turn together. +> - The knob's shank goes into the arm's small hole, with the knob's step resting on the arm's top face. The knob stays free to spin in its hole, like a handle. +> +> **10. UJoint.SLDASM:** +> - The bracket is fixed. +> - The male yoke hangs under the bracket's top arm. Its stub goes up through the bracket's hole (concentric), and the top of its cylinder is flat against the underside of the arm. It must stay free to turn in that hole. +> - The spider sits centred between the male yoke's ears, with one of its holes lined up with the ears' cross hole. It pivots on that axis. +> - The female yoke's ears go around the spider's other hole, centred on the spider. Its top face is parallel to the bracket's sloped lip, so its axis points down and forward. It pivots on the spider and turns about its own axis. +> - Put one pin through the male yoke's ears and the spider, and one pin through the female yoke's ears and the spider. Each pin's ends are flush with its yoke's round outside, and each pin turns with its yoke. +> - Insert the crank sub-assembly. Its shaft's D-socket goes over the male yoke's stub: concentric, with the flats parallel, and the bottom of the shaft 1 mm above the top of the bracket. The flats lock the crank to the male yoke. +> - The result should be a mechanism with one free motion: turning the knob around the crank shaft's axis turns the male yoke, the spider rocks on its pins, and the female yoke turns about its tilted axis. Choose mates that leave exactly those rotations free and lock everything else. +> +> When it's all built, check each part's size and the assembly's component and mate counts, say which rotations your mates leave free, and tell me what you couldn't do. + +
+ ![The original U-Joint sample beside the agent's build: the same bracket, yokes, spider, pins, crank and knob, in the same pose](docs/assets/demos/ujoint/ujoint_original_vs_agent.jpg) ![The agent's 294 tool calls replayed in SolidWorks: eight parts sketched and cut, then the crank sub-assembly and the U-joint mated together](docs/assets/demos/ujoint/test_ujoint_from_prompt_to_assembly-motion.gif) diff --git a/docs/assets/demos/monitor-stand/monitor_stand_printing.gif b/docs/assets/demos/monitor-stand/monitor_stand_printing.gif index 083abac2..da166e95 100644 Binary files a/docs/assets/demos/monitor-stand/monitor_stand_printing.gif and b/docs/assets/demos/monitor-stand/monitor_stand_printing.gif differ diff --git a/openspec/changes/agent-skill-and-instructions/.openspec.yaml b/openspec/changes/archive/2026-11-06-agent-skill-and-instructions/.openspec.yaml similarity index 100% rename from openspec/changes/agent-skill-and-instructions/.openspec.yaml rename to openspec/changes/archive/2026-11-06-agent-skill-and-instructions/.openspec.yaml diff --git a/openspec/changes/agent-skill-and-instructions/design.md b/openspec/changes/archive/2026-11-06-agent-skill-and-instructions/design.md similarity index 100% rename from openspec/changes/agent-skill-and-instructions/design.md rename to openspec/changes/archive/2026-11-06-agent-skill-and-instructions/design.md diff --git a/openspec/changes/agent-skill-and-instructions/proposal.md b/openspec/changes/archive/2026-11-06-agent-skill-and-instructions/proposal.md similarity index 100% rename from openspec/changes/agent-skill-and-instructions/proposal.md rename to openspec/changes/archive/2026-11-06-agent-skill-and-instructions/proposal.md diff --git a/openspec/changes/agent-skill-and-instructions/specs/agents/server-instructions/spec.md b/openspec/changes/archive/2026-11-06-agent-skill-and-instructions/specs/agents/server-instructions/spec.md similarity index 100% rename from openspec/changes/agent-skill-and-instructions/specs/agents/server-instructions/spec.md rename to openspec/changes/archive/2026-11-06-agent-skill-and-instructions/specs/agents/server-instructions/spec.md diff --git a/openspec/changes/agent-skill-and-instructions/specs/agents/usage-skill/spec.md b/openspec/changes/archive/2026-11-06-agent-skill-and-instructions/specs/agents/usage-skill/spec.md similarity index 100% rename from openspec/changes/agent-skill-and-instructions/specs/agents/usage-skill/spec.md rename to openspec/changes/archive/2026-11-06-agent-skill-and-instructions/specs/agents/usage-skill/spec.md diff --git a/openspec/changes/agent-skill-and-instructions/tasks.md b/openspec/changes/archive/2026-11-06-agent-skill-and-instructions/tasks.md similarity index 100% rename from openspec/changes/agent-skill-and-instructions/tasks.md rename to openspec/changes/archive/2026-11-06-agent-skill-and-instructions/tasks.md diff --git a/openspec/changes/tool-support-levels-and-progress/.openspec.yaml b/openspec/changes/tool-support-levels-and-progress/.openspec.yaml new file mode 100644 index 00000000..8a94d769 --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-11-06 diff --git a/openspec/changes/tool-support-levels-and-progress/design.md b/openspec/changes/tool-support-levels-and-progress/design.md new file mode 100644 index 00000000..11ad9f7e --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/design.md @@ -0,0 +1,70 @@ +## Context + +See proposal.md for why. Current state (counted 2026-11-06 on main): + +- 154 registered tools. 39 say "Not available yet" (the queue's not-available list). Of the other 115, 81 are called by name in a `tests/live/` test and 34 are not. Some of the 34 are run only by demo scripts that live tests load (`save_part`, `export_stl` via `scripts/demo_monitor_stand.py`), and some never touch SolidWorks at all (the `generate_vba_*` tools, `search_solidworks_api_help`, `find_related_api_members`). +- `tool_boundary.with_tool_metadata` already adds the family tag (`tool_family`, the module name) and the MCP hints at registration; the level tag and the `warning` fit in the same place. +- The type library (`sw_type_info`, gen_py) has 418 interfaces and 9,282 methods (5,985 distinct names). A plain text scan finds about 199 of those names called in `src/solidworks_mcp/adapters/`. gen_py only exists on Windows with SolidWorks, so CI can't read it. +- The docs site is MkDocs Material, deployed to GitHub Pages on push to main (`deploy-docs.yml`). +- the queue's small-faults list lists the known faults; the agent skill's `references/errors-and-limits.md` repeats them. + +## Goals / Non-Goals + +**Goals:** a level for every tool that a check keeps honest; the level visible to agents (tags, description, `warning`) and people (README bar, docs page); COM coverage measured the same way every time; the README image and page regenerate from one command, and a check catches when they weren't. + +**Non-Goals:** +- Fixing the faults or implementing planned tools (the queue's not-available and small-faults lists); this change only labels them. +- Licence-tier tags (#79's second half): a later change. +- Exact COM coverage. A name scan can't tell `IFeature.Name` from `IComponent2.Name`; the page says the figure is approximate. + +## Decisions + +### The table: `tools/support_levels.py` + +A dict `tool name -> (level, reason)` in one module, beside `tool_hints.py`, so a level is changed in one line. Alternative, a decorator argument on each tool: rejected, the levels would be spread over 15 modules and harder to review as a set. + +First assignment, by rule, then reviewed by hand with the user: +- `planned`: the 39 "Not available yet" tools; +- `beta`: a tool named in the queue's small-faults list or in `errors-and-limits.md` as having a fault, or known to cover only part of its COM call (`get_material`, `add_mate` without faces); +- `stable`: called by a live test or a demo script a live test runs, or a tool that never calls SolidWorks and is unit-tested (the VBA generators, the API lookups); +- `experimental`: the rest. + +### "Stable needs a live test", checked by text + +The check looks for the tool's name as a whole word in `tests/live/*.py` and in the `scripts/demo_*.py` files those tests load. Tools of the offline families (`vba_generation`, `type_library`, `docs_discovery`) are exempt. Alternative, recording which tools a live run actually called: rejected, live runs don't happen in CI. + +### Level in the payload: one optional `warning` key + +Added by the boundary to a successful result of a beta or experimental tool. It's additive, so existing clients and the stable payload shape (`status`, `message`, `execution_time`, data) are unaffected. Errors don't get it: they already carry `hint`. + +### COM snapshot: `docs/assets/progress/com_snapshot.json` + +`{sw_version, interfaces: {name: [methods]}}`, written by `src/utils/snapshot_com_api.py` (Windows only, run by hand after a SolidWorks upgrade). Committed so the generator and the check run anywhere. About 150 KB, acceptable. + +Core interfaces, fixed in the generator: `ISldWorks`, `IModelDoc2`, `IModelDocExtension`, `IPartDoc`, `IAssemblyDoc`, `IDrawingDoc`, `IFeatureManager`, `ISketchManager`, `ISelectionMgr`, `IComponent2`, `IFeature`, `ISketch`. Coverage of each = its method names called anywhere in the adapters, out of its methods. + +### Generator and check + +`src/utils/generate_progress.py` writes `docs/assets/progress/progress.svg` and `progress.json` (per tool: name, family, level, reason, first sentence of its description; per core interface: covered and total). `tests/integration/test_progress_up_to_date.py` builds both in memory and compares them with the committed files; on a mismatch it prints the command to run. Alternative, regenerating in CI and committing: rejected, CI shouldn't push to branches. + +### The SVG + +Hand-built SVG, no new dependency. A dark rounded panel; each bar a rounded track with a gloss highlight and diagonal stripes (a pattern), a soft outline. Tools bar: green `stable`, amber `beta`, orange `experimental`, the `planned` part left as the empty track. Core COM bar: a red-to-yellow-to-green gradient fill to its percentage. A legend with counts, and the whole-API figure in small print. Inspired by the reference the user shared; drawn from scratch. + +### The page: `docs/progress.md` + +The SVG, then a table of every tool rendered from `progress.json` at build time (a small MkDocs hook or a generated Markdown include, so it works without JavaScript), then `docs/javascripts/progress.js` adding level and family filter chips and hover details. Colours as in the SVG, with a text label as well as colour on every row. + +## Risks / Trade-offs + +- [Levels get stale as tools change] → the checks above fail on the cases that can be detected; the queue's small-faults note says a fixed fault moves its tool up a level. +- [The COM figure reads as low] → the core-interface bar is the headline; the whole-API figure is small print with an explanation on the page. +- [Description openings change for ~20 tools] → agents see the change at the next connection; the description check covers it. + +## Migration Plan + +Additive. Clients ignoring tags and `warning` see no change apart from description openings. Rollback is removing the table and the boundary lines; the generated files can stay. + +## Open Questions + +- The hand review of the first assignment: the user decides the borderline tools (in tasks 1.2). diff --git a/openspec/changes/tool-support-levels-and-progress/proposal.md b/openspec/changes/tool-support-levels-and-progress/proposal.md new file mode 100644 index 00000000..e6de7247 --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/proposal.md @@ -0,0 +1,33 @@ +## Why + +Nothing in the tool list tells you how far to trust a tool. A tool that has been checked on real SolidWorks and uses every input sits beside one that ignores half its inputs (the queue's small-faults list) or one that can't run at all (the 39 tools in the queue's not-available list). People landing on the repo also can't see how much of SolidWorks the project covers, or that it is two things at once: a Python library for scripting SolidWorks and an MCP server for agents. #79 asked for the coverage audit; the user asked on 2026-11-06 for it as a progress bar at the top of the README, kept up to date as tools are added. + +## What Changes + +- Every registered tool gets exactly one **support level**, kept in a single table: + - `stable`: checked by a live test on real SolidWorks, every input used, no known fault; + - `beta`: works on SolidWorks, but has a known fault or covers only part of its COM call (e.g. `get_material` reads the name and library only); + - `experimental`: implemented, never checked on real SolidWorks; + - `planned`: registered but not implemented (today's "Not available yet" tools). +- A tool's level shows in three places: its tags (`level:beta`, next to the family tag), the start of its description (beta and experimental tools say so first), and its results (a beta or experimental tool's success adds a short `warning`). +- A check fails when the table and the code disagree: a tool missing from the table, a `planned` tool whose description doesn't say "Not available yet" (or the reverse), or a `stable` tool with no live test. +- **COM coverage:** a committed snapshot of the SolidWorks type library (interface → method names, made on Windows with a small script) and a scan of the adapter code for the COM methods it calls. Coverage is counted for a fixed list of core interfaces (application, document, part, assembly, drawing, sketch, feature, selection) and for the whole API. +- **The progress bars:** a generator writes one SVG (two glossy, striped, rounded bars on a dark panel: the tools bar split by level colour, the core-COM bar filled red to green, the whole-API figure in small print) and the data behind it. A check fails when the committed SVG or data is out of date, so adding a tool means regenerating them. +- **An interactive page** on the docs site: the same bars, then every tool and every core interface, filterable by level and family, coloured by level, with each tool's description and the COM methods it reaches on hover. +- **README:** the bar at the top, linking to the page, and a short "two tools in one" section: a Python interface for scripting SolidWorks, and an MCP tool server on top of it. + +## Capabilities + +### New Capabilities +- `tools/support-levels`: one support level per tool, shown in its tags, description and results, and checked against the code. +- `docs/coverage-progress`: the COM snapshot, the coverage count, the generated progress SVG and interactive page, and the staleness check. + +### Modified Capabilities +- `tools/tool-descriptions`: a beta or experimental tool's description opens with its level, as a "Not available yet" tool's already does. + +## Impact + +- New: `src/solidworks_mcp/tools/support_levels.py` (the table), a generator under `src/utils/`, `docs/assets/progress/` (SVG and data), a docs page with a small script, tests beside each module plus a cross-module check in `tests/integration/`. +- Changed: `tool_boundary.py` (adds the level tag and the `warning`), descriptions of the beta and experimental tools, README, mkdocs nav. +- No COM or adapter code changes: the adapter is only read, as text. The type-library snapshot script needs Windows with SolidWorks, but the check and the generator run anywhere from the committed snapshot. +- Addresses #79 (the coverage half; licence-tier tags are left for later). Feeds #174 (cleanup) and the queue's not-available and small-faults lists, which move tools between levels. diff --git a/openspec/changes/tool-support-levels-and-progress/specs/docs/coverage-progress/spec.md b/openspec/changes/tool-support-levels-and-progress/specs/docs/coverage-progress/spec.md new file mode 100644 index 00000000..f210e152 --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/specs/docs/coverage-progress/spec.md @@ -0,0 +1,37 @@ +## ADDED Requirements + +### Requirement: COM coverage is counted from a committed snapshot + +The project SHALL keep a snapshot of the SolidWorks type library's interface and method names, and count coverage by scanning the adapter source for those method names, without needing SolidWorks. + +#### Scenario: Counting coverage +- **WHEN** the generator runs on any platform +- **THEN** it reports, for each core interface, the methods the adapters call out of its total, and the same for the whole API, from the snapshot and the adapter source only + +#### Scenario: Refreshing the snapshot +- **WHEN** the snapshot script runs on Windows with SolidWorks installed +- **THEN** it rewrites the snapshot from the installed type library and records the SolidWorks version it came from + +### Requirement: Progress bars at the top of the README + +The README SHALL open with a generated progress image: the tools by support level and the core COM coverage, with the whole-API figure, linking to the interactive page. + +#### Scenario: The image matches the code +- **WHEN** a tool, a level or the adapter's COM calls change and the image and data are not regenerated +- **THEN** the progress check fails and says which command regenerates them + +#### Scenario: Readable in both themes +- **WHEN** the README is viewed in GitHub's light or dark theme +- **THEN** the image draws its own dark panel, so the bars and their text look the same + +### Requirement: An interactive progress page + +The docs site SHALL have a page with the same bars and every tool and core interface, filterable by level and family. + +#### Scenario: Filtering +- **WHEN** a reader picks a level or a family +- **THEN** only the matching tools are shown, each coloured by its level, with its description on hover + +#### Scenario: Without JavaScript +- **WHEN** the page is read without scripts +- **THEN** the bars and a plain table of every tool and its level still show diff --git a/openspec/changes/tool-support-levels-and-progress/specs/tools/support-levels/spec.md b/openspec/changes/tool-support-levels-and-progress/specs/tools/support-levels/spec.md new file mode 100644 index 00000000..2bf5a8d1 --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/specs/tools/support-levels/spec.md @@ -0,0 +1,41 @@ +## ADDED Requirements + +### Requirement: One support level per tool + +Every registered tool SHALL have exactly one support level, `stable`, `beta`, `experimental` or `planned`, recorded in one table, with a one-line reason for every level below `stable`. + +#### Scenario: A new tool without a level +- **WHEN** a tool is registered that the table does not list +- **THEN** the support-level check fails and names the tool + +#### Scenario: A listed tool that no longer exists +- **WHEN** the table lists a name that no registered tool has +- **THEN** the check fails and names it + +### Requirement: Levels are consistent with the code + +The check SHALL fail when a level contradicts what the code shows. + +#### Scenario: Planned means not implemented +- **WHEN** a tool is `planned` +- **THEN** its description says "Not available yet", and no tool outside `planned` says so + +#### Scenario: Stable means checked live +- **WHEN** a tool is `stable` +- **THEN** at least one test under `tests/live/` calls it by name + +### Requirement: The level is visible to clients + +A tool's level SHALL be shown in its tags and, below `stable`, in its results. + +#### Scenario: Tags +- **WHEN** a client lists the tools +- **THEN** each tool's tags include `level:` beside its family tag + +#### Scenario: A beta tool succeeds +- **WHEN** a `beta` or `experimental` tool returns `status: success` +- **THEN** the result also carries `warning`, a sentence giving the level and its reason, and every other key is unchanged + +#### Scenario: A stable tool succeeds +- **WHEN** a `stable` tool returns `status: success` +- **THEN** the result has no `warning` key diff --git a/openspec/changes/tool-support-levels-and-progress/specs/tools/tool-descriptions/spec.md b/openspec/changes/tool-support-levels-and-progress/specs/tools/tool-descriptions/spec.md new file mode 100644 index 00000000..e4a5d9bc --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/specs/tools/tool-descriptions/spec.md @@ -0,0 +1,13 @@ +## ADDED Requirements + +### Requirement: A description states a level below stable + +A `beta` or `experimental` tool's description SHALL open with its level and the reason, in one short sentence, before what the tool does. + +#### Scenario: A beta tool +- **WHEN** an agent reads a `beta` tool's description +- **THEN** its first sentence starts "Beta:" and names the gap, e.g. "Beta: reads the material's name and library, not its properties." + +#### Scenario: The level changes +- **WHEN** a tool's level changes in the table +- **THEN** the description check fails until the opening sentence matches the new level diff --git a/openspec/changes/tool-support-levels-and-progress/tasks.md b/openspec/changes/tool-support-levels-and-progress/tasks.md new file mode 100644 index 00000000..5bcd9bee --- /dev/null +++ b/openspec/changes/tool-support-levels-and-progress/tasks.md @@ -0,0 +1,29 @@ +## 1. Support levels + +- [ ] 1.1 `src/solidworks_mcp/tools/support_levels.py`: the table, filled by the rules in design.md; tests in `tests/solidworks_mcp/tools/test_support_levels.py` +- [ ] 1.2 Review the first assignment with the user, tool by tool for the borderline ones; record the reasons +- [ ] 1.3 `tool_boundary.py`: add the `level:` tag and the `warning` on beta/experimental successes; tests beside it +- [ ] 1.4 `tests/integration/test_support_levels.py`: every tool listed, no stale names, planned ⇔ "Not available yet", stable has a live test or is offline +- [ ] 1.5 Rewrite the opening sentence of every beta and experimental tool's description; extend the description check + +## 2. COM coverage + +- [ ] 2.1 `src/utils/snapshot_com_api.py` (Windows, by hand) and the committed `docs/assets/progress/com_snapshot.json` +- [ ] 2.2 The adapter scan and core-interface coverage, with tests on a small fixture + +## 3. Progress image, data and page + +- [ ] 3.1 `src/utils/generate_progress.py`: `progress.svg` and `progress.json`; tests +- [ ] 3.2 `tests/integration/test_progress_up_to_date.py`: fails when either is stale, naming the command +- [ ] 3.3 `docs/progress.md` with the no-script table and `docs/javascripts/progress.js` filters; mkdocs nav; `mkdocs build --strict` +- [ ] 3.4 Show the user the SVG and the page before wiring them into the README + +## 4. README and docs + +- [ ] 4.1 README: the progress image at the top linking to the page; a "two tools in one" section (Python interface for scripting SolidWorks, and an MCP server on it) +- [ ] 4.2 `docs/agents/tool-description-standard.md` and the agent skill: what the levels mean; the queue's small-faults list note: a fixed fault moves its tool up a level +- [ ] 4.3 CHANGELOG; `openspec/queue.md` (this change before #179; #79's coverage half done) + +## 5. Ship + +- [ ] 5.1 Full mock suite, ruff, 100 % coverage, `mkdocs build --strict` diff --git a/openspec/queue.md b/openspec/queue.md index b4beec73..01d0b9ad 100644 --- a/openspec/queue.md +++ b/openspec/queue.md @@ -11,7 +11,7 @@ Last updated 2026-11-06. | # | Item | Issue | OpenSpec change | State | | --- | --- | --- | --- | --- | | 1 | Tool descriptions agents can act on: one description standard, MCP hints and family tags, and a check that keeps them | #82 (docstring half) | `tool-descriptions-for-agents` (archived) | Done 2026-11-05 (#202, #203, #204). Left: after the next release, ask Glama for a rescan and record the score in the internal assessment | -| 2 | Guidance through MCP and an installable skill: the server's `instructions`, the skill served as `skill://` resources with FastMCP 3.4.9's `SkillProvider`, and the same skill installable into an agent | #175 | `agent-skill-and-instructions` | Merged (#205). Measured 2026-11-06 on the U-joint; the demo and write-up ship in the U-joint demo PR, which also closes #147 (superseded) | +| 2 | Guidance through MCP and an installable skill: the server's `instructions`, the skill served as `skill://` resources with FastMCP 3.4.9's `SkillProvider`, and the same skill installable into an agent | #175 | `agent-skill-and-instructions` (archived) | Done 2026-11-06 (#205, #211; #147 closed as superseded) | | 3 | The circuit breaker locks a tool out after a success and never reopens; a reset tool | #208 | not yet written | Next | | 4 | Support levels for every tool, and COM coverage progress bars at the top of the README with an interactive docs page | #79 (coverage half) | `tool-support-levels-and-progress` | Plan written 2026-11-06, in review | | 5 | Tool gaps found building the U-joint: face mates, fixed parts and flexible sub-assemblies, angled planes, angled chamfers, `both_directions`, a stale interference result, thin extrudes | #209 | not yet written | | diff --git a/openspec/specs/agents/server-instructions/spec.md b/openspec/specs/agents/server-instructions/spec.md new file mode 100644 index 00000000..b63cc58c --- /dev/null +++ b/openspec/specs/agents/server-instructions/spec.md @@ -0,0 +1,33 @@ +# agents/server-instructions Specification + +## Purpose +TBD - created by archiving change agent-skill-and-instructions. Update Purpose after archive. +## Requirements +### Requirement: The server sends short usage instructions at connection + +The server SHALL send an `instructions` text in its MCP initialize response. +It SHALL be at most 1500 characters and SHALL say: + +- to call `get_model_info` (or `list_open_documents`) first, to see what is + open; +- the build order: `create_sketch`, draw, `exit_sketch`, then the feature; +- that inputs are millimetres and degrees unless a field says otherwise; +- to finish a build with `verify_model`, since a tool's success does not + prove the geometry; +- that tools whose description starts "Not available yet" return + `not_supported`; +- where the full guidance is: the `skill://solidworks-mcp/SKILL.md` resource. + +Every tool it names SHALL be a registered tool. + +#### Scenario: A client connects + +- **WHEN** an MCP client initializes a session with the server +- **THEN** the response carries the instructions text +- **AND** it names `skill://solidworks-mcp/SKILL.md` + +#### Scenario: The instructions name a removed tool + +- **WHEN** a tool named in the instructions is no longer registered +- **THEN** the test suite fails, naming the tool + diff --git a/openspec/specs/agents/usage-skill/spec.md b/openspec/specs/agents/usage-skill/spec.md new file mode 100644 index 00000000..889d0ee3 --- /dev/null +++ b/openspec/specs/agents/usage-skill/spec.md @@ -0,0 +1,100 @@ +# agents/usage-skill Specification + +## Purpose +TBD - created by archiving change agent-skill-and-instructions. Update Purpose after archive. +## Requirements +### Requirement: The skill teaches cross-tool use of the server + +The package SHALL include a skill named `solidworks-mcp`: a `SKILL.md` with +a name and a description in its frontmatter, plus reference files. It SHALL +cover: + +- the build order: create or open a document, `create_sketch`, draw, + `exit_sketch`, then the feature tool; and `verify_model` as the last step; +- units: inputs in millimetres and degrees, naming each input that takes + metres instead; +- choosing planes, faces and edges, and preferring a whole face over a point + on an edge; +- reading back after every change, and what a success does and does not + prove; +- recovering from a failure (`rebuild_model`, `undo`, `get_model_info`); +- the tools that can't run yet and the known faults agents must work around; +- when to use the VBA generation tools instead. + +`SKILL.md` SHALL stay under 500 lines and put detail in the reference files. + +#### Scenario: An agent reads the skill + +- **WHEN** an agent loads `SKILL.md` +- **THEN** its frontmatter has `name: solidworks-mcp` and a description that + says when to use it +- **AND** its body lists the build order and the unit rule + +### Requirement: The skill names only real tools, correctly + +Every tool name the skill mentions SHALL be a tool the server registers. A +tool the skill tells agents to call SHALL NOT be one that can't run yet +(every call returns `not_supported`). + +#### Scenario: A tool is renamed or removed + +- **WHEN** a tool the skill names is no longer registered +- **THEN** the test suite fails, naming the tool and the skill file + +#### Scenario: The skill recommends a tool that can't run + +- **WHEN** the skill's build steps name a tool that returns `not_supported` + for every call +- **THEN** the test suite fails + +### Requirement: The server serves the skill + +The server SHALL expose the skill as MCP resources: `SKILL.md` at +`skill://solidworks-mcp/SKILL.md`, a manifest listing its files, and each +reference file. Reading them SHALL need no SolidWorks connection. + +#### Scenario: A client lists the server's resources + +- **WHEN** a client lists resources on a running server, in mock mode or real +- **THEN** `skill://solidworks-mcp/SKILL.md` is listed +- **AND** reading it returns the same text as the packaged `SKILL.md` + +### Requirement: One command installs the skill into an agent + +`solidworks-mcp skill install` SHALL copy the packaged skill into +`/solidworks-mcp/`. The skills folder SHALL be Claude Code's +user folder (`~/.claude/skills`) by default, the current project's +`.claude/skills` with `--project`, or any folder given with `--dir`. It +SHALL report the path it wrote. + +It SHALL write only inside `/solidworks-mcp/`, SHALL NOT read +or change any other file (no client config, no other skill), and SHALL work +offline with no account or token. When the folder already holds the skill, +it SHALL replace the packaged files and leave any other file in that folder +alone. `--dry-run` SHALL report what it would write without writing. + +#### Scenario: First install for Claude Code + +- **WHEN** a user runs `solidworks-mcp skill install` +- **THEN** `~/.claude/skills/solidworks-mcp/SKILL.md` exists, identical to + the packaged one +- **AND** the command prints that path + +#### Scenario: Upgrading after a new release + +- **WHEN** the skill folder already holds an older copy and a file the user + added +- **THEN** the packaged files are replaced +- **AND** the user's file is unchanged + +#### Scenario: Another agent + +- **WHEN** a user runs `solidworks-mcp skill install --dir ` +- **THEN** the skill is written to `/solidworks-mcp/` + +#### Scenario: The target can't be written + +- **WHEN** the skills folder can't be created or written +- **THEN** the command exits with an error that names the path +- **AND** nothing outside that path has changed +