diff --git a/CLAUDE.md b/CLAUDE.md index 6b83fb4..d08b4d0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -31,8 +31,11 @@ The index lives at `docs/kompas_sdk_index.tsv` (`filenametitleexcerpt` ## Current state -**v1 implemented and working** (sketch→extrude→snapshot loop validated end-to-end over MCP). Stack: +**v1 + v2 implemented and working** (full sketch→feature→inspect loop validated end-to-end). Stack: **.NET 8 (`net8.0-windows`, x64), C#**, MCP via the official `ModelContextProtocol` SDK over **stdio**. +**28 MCP tools, 18 tests green.** v2 added: sketch-on-face (by point and by index), revolve (boss/cut + +sketch axis), fillet/chamfer (edge-by-point), and Query tools `get_part_info` (МЦХ), `get_bounding_box`, +`list_faces`. See [`README.md`](README.md) and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md); design decisions/caveats in [`docs/OPEN_QUESTIONS.md`](docs/OPEN_QUESTIONS.md). @@ -50,10 +53,12 @@ dotnet run --project src/Kompas.Mcp.Host # start the MCP server (stdio) Key implementation facts (don't relearn): - **All COM calls run on one dedicated STA thread** (`KompasDispatcher.InvokeAsync`); КОМПАС is single-instance STA. Services never touch COM off that thread. - Connection goes through **API5** (`KOMPAS.Application.5` → `KompasObject`) then `ksGetApplication7()` → `IApplication`; the API5 root is needed for `ksPart` 3D-building and `ksDocument3D` snapshots. -- 3D is built via **API5 `ksPart`** (`NewEntity(o3d_sketch/o3d_bossExtrusion/...)`, `ksBossExtrusionDefinition`/`ksCutExtrusionDefinition`); cut-through holes use `dtBoth` + `etThroughAll`. API7 is used for app/documents. +- 3D is built via **API5 `ksPart`** (`NewEntity(o3d_sketch/o3d_bossExtrusion/o3d_bossRotated/o3d_fillet/o3d_chamfer/...)`, `ksBossExtrusionDefinition`/`ksCutExtrusionDefinition`/`ksBossRotatedDefinition`/`ksFilletDefinition`/`ksChamferDefinition`); cut-through holes use `dtBoth` + `etThroughAll`. API7 is used for app/documents. +- **Face/edge selection**: `ksPart.EntityCollection(o3d_face|o3d_edge)` → `SelectByPoint(x,y,z)` (world mm) filters to objects through the point, then `GetByIndex(0)`; or by stable index from `list_faces`. `ksFaceDefinition.IsPlanar/IsCylinder/...` + `GetArea(ST_MIX_MM)` classify faces. Sketch axis = line with system style **3** (осевая). +- **МЦХ / mass props**: use **API5 `ksPart.CalcMassInertiaProperties(ST_MIX_MM|ST_MIX_KG)`** → `ksMassInertiaParam` (`v`/`m`/`F`/`xc`/`yc`/`zc`), computed on demand. **Do NOT** use API7 `IMassInertiaParam7.Calculate()` — its `Actual` flag sticks after the first calc and won't refresh on API5 geometry changes (stale volume). Bounding box: `ksPart.GetGabarit(full:false, ...)`. - **Snapshot**: `ksDocument3D.SaveAsToRasterFormat(file, ksRasterFormatParam)` renders to a temp file (the in-memory `resultArrayBytes` stays empty when a filename is given); read bytes back. Return to MCP via `ImageContentBlock.FromBytes(bytes, mime)` — **not** `Data = bytes` (Data holds base64 bytes). - Logs go to **stderr** (stdout is the MCP channel). Integration tests reuse one КОМПАС via `KompasFixture`; artifacts land in gitignored `.scratch/`. -- Not yet done (next): face selection / sketch-on-face, revolve, fillet/chamfer, `get_part_info` (mass/volume), variables/properties, a proper in-process MCP-client test. +- Not yet done (next): patterns/arrays, `list_bodies`/`list_edges`, variables/properties (`IVariable7`), 2D drawing, assemblies, a proper in-process MCP-client test. Known caveat: boss/cut direction on a selected face depends on face-normal orientation (`forward` may need flipping — agent picks via snapshot). See `docs/OPEN_QUESTIONS.md` → «Ревью v2». ## КОМПАС-3D API architecture (the critical context)