@vcad/mcp 0.9.4-main.27 → 0.9.4-main.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.mjs +197 -15
- package/package.json +3 -3
- package/vcad_kernel_wasm_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -6,4 +6,4 @@ vcad's MCP server as a self-contained bundle (server + BRep kernel WASM).
|
|
|
6
6
|
{ "mcpServers": { "vcad": { "command": "npx", "args": ["-y", "@vcad/mcp"] } } }
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Built from
|
|
9
|
+
Built from d80a65e336d1c8b8ebf75dd1bebc553b41f7ca93 at 2026-07-26T00:45:54.095Z. Source: https://github.com/ecto/vcad
|
package/index.mjs
CHANGED
|
@@ -113,6 +113,7 @@ __export(vcad_kernel_wasm_exports, {
|
|
|
113
113
|
documentToLoonChecked: () => documentToLoonChecked,
|
|
114
114
|
drawingSheetToPdf: () => drawingSheetToPdf,
|
|
115
115
|
ecadAirgapFluxDensity: () => ecadAirgapFluxDensity,
|
|
116
|
+
ecadAirgapSolve: () => ecadAirgapSolve,
|
|
116
117
|
ecadBuildReceipt: () => ecadBuildReceipt,
|
|
117
118
|
ecadBuiltinSymbols: () => ecadBuiltinSymbols,
|
|
118
119
|
ecadCheckDrc: () => ecadCheckDrc,
|
|
@@ -1142,6 +1143,15 @@ function ecadAirgapFluxDensity(spec_json) {
|
|
|
1142
1143
|
}
|
|
1143
1144
|
return ret[0];
|
|
1144
1145
|
}
|
|
1146
|
+
function ecadAirgapSolve(spec_json) {
|
|
1147
|
+
const ptr0 = passStringToWasm0(spec_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1148
|
+
const len0 = WASM_VECTOR_LEN;
|
|
1149
|
+
const ret = wasm.ecadAirgapSolve(ptr0, len0);
|
|
1150
|
+
if (ret[2]) {
|
|
1151
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1152
|
+
}
|
|
1153
|
+
return takeFromExternrefTable0(ret[0]);
|
|
1154
|
+
}
|
|
1145
1155
|
function ecadBuildReceipt(pcb_json) {
|
|
1146
1156
|
const ptr0 = passStringToWasm0(pcb_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
1147
1157
|
const len0 = WASM_VECTOR_LEN;
|
|
@@ -10367,6 +10377,20 @@ async function airgapFluxDensity(spec) {
|
|
|
10367
10377
|
return null;
|
|
10368
10378
|
}
|
|
10369
10379
|
}
|
|
10380
|
+
async function airgapSolve(spec) {
|
|
10381
|
+
const wasm3 = await loadEcadWasm();
|
|
10382
|
+
if (!wasm3)
|
|
10383
|
+
return null;
|
|
10384
|
+
try {
|
|
10385
|
+
const fn = wasm3.ecadAirgapSolve;
|
|
10386
|
+
if (typeof fn !== "function")
|
|
10387
|
+
return null;
|
|
10388
|
+
return fn(JSON.stringify(spec));
|
|
10389
|
+
} catch (e) {
|
|
10390
|
+
console.warn("[ECAD] airgapSolve failed:", e);
|
|
10391
|
+
return null;
|
|
10392
|
+
}
|
|
10393
|
+
}
|
|
10370
10394
|
async function generateNetlist(sheet) {
|
|
10371
10395
|
const wasm3 = await loadEcadWasm();
|
|
10372
10396
|
if (!wasm3)
|
|
@@ -11229,6 +11253,7 @@ __export(dist_exports, {
|
|
|
11229
11253
|
PhysicsEnv: () => PhysicsEnv,
|
|
11230
11254
|
SolidCache: () => SolidCache,
|
|
11231
11255
|
airgapFluxDensity: () => airgapFluxDensity,
|
|
11256
|
+
airgapSolve: () => airgapSolve,
|
|
11232
11257
|
applyForwardKinematics: () => applyForwardKinematics,
|
|
11233
11258
|
buildMoleculeReceipt: () => buildReceipt2,
|
|
11234
11259
|
buildPartDocument: () => buildPartDocument,
|
|
@@ -40898,6 +40923,26 @@ var init_CHANGELOG = __esm({
|
|
|
40898
40923
|
"sheet_metal_create"
|
|
40899
40924
|
]
|
|
40900
40925
|
},
|
|
40926
|
+
{
|
|
40927
|
+
id: "2026-07-25-shell-and-booleans-on-filleted-solids",
|
|
40928
|
+
version: "0.9.4",
|
|
40929
|
+
date: "2026-07-25",
|
|
40930
|
+
category: "fix",
|
|
40931
|
+
title: "Shelling and cutting a filleted solid no longer leaks",
|
|
40932
|
+
summary: "Hollowing a filleted part scattered its cavity and a pocket cut collapsed the neighboring blends flat; both are now exact and watertight, and the kernel is reproducible run to run.",
|
|
40933
|
+
features: [
|
|
40934
|
+
"kernel",
|
|
40935
|
+
"fillet",
|
|
40936
|
+
"shell",
|
|
40937
|
+
"booleans",
|
|
40938
|
+
"tessellation"
|
|
40939
|
+
],
|
|
40940
|
+
mcpTools: [
|
|
40941
|
+
"create_cad_loon",
|
|
40942
|
+
"inspect_cad",
|
|
40943
|
+
"export_cad"
|
|
40944
|
+
]
|
|
40945
|
+
},
|
|
40901
40946
|
{
|
|
40902
40947
|
id: "2026-07-25-router-window-repair-commit-parity",
|
|
40903
40948
|
version: "0.9.4",
|
|
@@ -41169,6 +41214,57 @@ var init_CHANGELOG = __esm({
|
|
|
41169
41214
|
"quote_manufacturing"
|
|
41170
41215
|
]
|
|
41171
41216
|
},
|
|
41217
|
+
{
|
|
41218
|
+
id: "2026-07-25-em-saturated-picard",
|
|
41219
|
+
version: "0.9.4",
|
|
41220
|
+
date: "2026-07-25",
|
|
41221
|
+
category: "fix",
|
|
41222
|
+
title: "simulate_em solves strongly saturating magnetostatics",
|
|
41223
|
+
summary: "Saturated motor cross-sections no longer fail with an unfixable 'Picard not converged': the nonlinear loop's cap, tolerance and relaxation are now caller-settable, and the default cap was raised.",
|
|
41224
|
+
features: [
|
|
41225
|
+
"em",
|
|
41226
|
+
"magnetostatics",
|
|
41227
|
+
"motors"
|
|
41228
|
+
],
|
|
41229
|
+
mcpTools: [
|
|
41230
|
+
"simulate_em"
|
|
41231
|
+
]
|
|
41232
|
+
},
|
|
41233
|
+
{
|
|
41234
|
+
id: "2026-07-25-curved-trim-seams-weld",
|
|
41235
|
+
version: "0.9.4",
|
|
41236
|
+
date: "2026-07-25",
|
|
41237
|
+
category: "fix",
|
|
41238
|
+
title: "Bores and cut curved faces close their seams",
|
|
41239
|
+
summary: "A through-hole left the shell open along the bore wall \u2014 visible as hairline cracks and unusable for 3D print or STL export; bores, holed plates and cut fillet corners now come out watertight.",
|
|
41240
|
+
features: [
|
|
41241
|
+
"kernel",
|
|
41242
|
+
"booleans",
|
|
41243
|
+
"tessellation",
|
|
41244
|
+
"export"
|
|
41245
|
+
],
|
|
41246
|
+
mcpTools: [
|
|
41247
|
+
"create_cad_loon",
|
|
41248
|
+
"inspect_cad",
|
|
41249
|
+
"export_cad"
|
|
41250
|
+
]
|
|
41251
|
+
},
|
|
41252
|
+
{
|
|
41253
|
+
id: "2026-07-25-calc-motor-tooth-saturation",
|
|
41254
|
+
version: "0.9.4",
|
|
41255
|
+
date: "2026-07-25",
|
|
41256
|
+
category: "fix",
|
|
41257
|
+
title: "calc_motor sees saturating stator teeth",
|
|
41258
|
+
summary: "calc_motor's MEC model treated iron as linear and silently over-predicted Kt on machines whose teeth saturate; it now reports tooth flux, warns past the knee, and can solve the saturating network.",
|
|
41259
|
+
features: [
|
|
41260
|
+
"motor",
|
|
41261
|
+
"magnetics",
|
|
41262
|
+
"simulation"
|
|
41263
|
+
],
|
|
41264
|
+
mcpTools: [
|
|
41265
|
+
"calc_motor"
|
|
41266
|
+
]
|
|
41267
|
+
},
|
|
41172
41268
|
{
|
|
41173
41269
|
id: "2026-07-24-visionos-app",
|
|
41174
41270
|
version: "0.9.4",
|
|
@@ -64125,6 +64221,7 @@ async function calcMotor(args) {
|
|
|
64125
64221
|
let bGap = num2(args.airgap_flux_tesla);
|
|
64126
64222
|
let bGapSource = "supplied";
|
|
64127
64223
|
let magnetSpec;
|
|
64224
|
+
let solution = null;
|
|
64128
64225
|
let fringing;
|
|
64129
64226
|
if (!Number.isFinite(bGap)) {
|
|
64130
64227
|
const m = args.magnet ?? {};
|
|
@@ -64138,15 +64235,55 @@ async function calcMotor(args) {
|
|
|
64138
64235
|
gapAreaMm2: mnum(m.gap_area_mm2, 1),
|
|
64139
64236
|
ironMuRel: typeof m.iron_mu_rel === "number" ? m.iron_mu_rel : null,
|
|
64140
64237
|
ironPathMm: mnum(m.iron_path_mm, 0),
|
|
64141
|
-
ironAreaMm2: mnum(m.iron_area_mm2, 1)
|
|
64142
|
-
|
|
64143
|
-
|
|
64144
|
-
if (
|
|
64145
|
-
|
|
64146
|
-
|
|
64147
|
-
);
|
|
64238
|
+
ironAreaMm2: mnum(m.iron_area_mm2, 1),
|
|
64239
|
+
ironJsT: typeof m.iron_js_t === "number" ? m.iron_js_t : null
|
|
64240
|
+
};
|
|
64241
|
+
if (m.slots !== void 0) {
|
|
64242
|
+
const slots = num2(m.slots);
|
|
64243
|
+
if (!(slots > 0)) return fail2("magnet.slots must be > 0");
|
|
64244
|
+
const meanR = Number.isFinite(num2(m.mean_radius_mm)) ? num2(m.mean_radius_mm) : (innerR + outerR) / 2;
|
|
64245
|
+
const pitch = 2 * Math.PI * meanR / slots;
|
|
64246
|
+
let toothW = num2(m.tooth_width_mm);
|
|
64247
|
+
if (!Number.isFinite(toothW)) {
|
|
64248
|
+
const frac = num2(m.tooth_fraction);
|
|
64249
|
+
if (!Number.isFinite(frac)) {
|
|
64250
|
+
return fail2("magnet.slots requires magnet.tooth_width_mm or magnet.tooth_fraction");
|
|
64251
|
+
}
|
|
64252
|
+
if (!(frac > 0 && frac <= 1)) return fail2("magnet.tooth_fraction must be in (0, 1]");
|
|
64253
|
+
toothW = frac * pitch;
|
|
64254
|
+
}
|
|
64255
|
+
if (!(toothW > 0)) return fail2("magnet.tooth_width_mm must be > 0");
|
|
64256
|
+
magnetSpec.teeth = {
|
|
64257
|
+
slots,
|
|
64258
|
+
toothWidthMm: toothW,
|
|
64259
|
+
meanRadiusMm: meanR,
|
|
64260
|
+
toothPathMm: mnum(m.tooth_path_mm, 0)
|
|
64261
|
+
};
|
|
64262
|
+
}
|
|
64263
|
+
solution = await airgapSolve(magnetSpec);
|
|
64264
|
+
if (solution == null) {
|
|
64265
|
+
const computed = await airgapFluxDensity(magnetSpec);
|
|
64266
|
+
if (computed == null) {
|
|
64267
|
+
return fail2(
|
|
64268
|
+
"air-gap flux is required: pass airgap_flux_tesla, or `magnet` params (ECAD WASM must be available to compute B_gap)."
|
|
64269
|
+
);
|
|
64270
|
+
}
|
|
64271
|
+
const t2 = magnetSpec.teeth;
|
|
64272
|
+
const k = t2 ? Math.max(1, 2 * Math.PI * t2.meanRadiusMm / t2.slots / t2.toothWidthMm) : null;
|
|
64273
|
+
solution = {
|
|
64274
|
+
bGapTesla: computed,
|
|
64275
|
+
bToothTesla: k == null ? null : computed * k,
|
|
64276
|
+
bIronTesla: null,
|
|
64277
|
+
toothConcentration: k,
|
|
64278
|
+
nonlinear: false,
|
|
64279
|
+
iterations: 0,
|
|
64280
|
+
converged: true,
|
|
64281
|
+
warnings: k != null && computed * k > SILICON_STEEL_KNEE_T ? [
|
|
64282
|
+
`tooth flux density ${(computed * k).toFixed(2)} T exceeds the ${SILICON_STEEL_KNEE_T.toFixed(2)} T knee \u2014 the LINEAR iron model over-predicts B_gap and Kt here; pass magnet.iron_js_t to solve the saturating network`
|
|
64283
|
+
] : []
|
|
64284
|
+
};
|
|
64148
64285
|
}
|
|
64149
|
-
bGap =
|
|
64286
|
+
bGap = solution.bGapTesla;
|
|
64150
64287
|
bGapSource = "computed";
|
|
64151
64288
|
if (m.pole_width_mm !== void 0) {
|
|
64152
64289
|
const poleW = num2(m.pole_width_mm);
|
|
@@ -64218,6 +64355,24 @@ async function calcMotor(args) {
|
|
|
64218
64355
|
})
|
|
64219
64356
|
);
|
|
64220
64357
|
}
|
|
64358
|
+
if (solution?.bToothTesla != null && magnetSpec.teeth) {
|
|
64359
|
+
claims.push(
|
|
64360
|
+
emClaim(
|
|
64361
|
+
"tooth_flux_density",
|
|
64362
|
+
r4(solution.bToothTesla),
|
|
64363
|
+
"T",
|
|
64364
|
+
solution.nonlinear ? "mec-saturating-iron" : "mec-tooth-concentration",
|
|
64365
|
+
{
|
|
64366
|
+
...mecInputs,
|
|
64367
|
+
slots: magnetSpec.teeth.slots,
|
|
64368
|
+
tooth_width_mm: r4(magnetSpec.teeth.toothWidthMm),
|
|
64369
|
+
mean_radius_mm: r4(magnetSpec.teeth.meanRadiusMm),
|
|
64370
|
+
tooth_concentration: r4(solution.toothConcentration ?? 1),
|
|
64371
|
+
...magnetSpec.ironJsT != null ? { iron_js_t: magnetSpec.ironJsT } : {}
|
|
64372
|
+
}
|
|
64373
|
+
)
|
|
64374
|
+
);
|
|
64375
|
+
}
|
|
64221
64376
|
}
|
|
64222
64377
|
return {
|
|
64223
64378
|
content: [
|
|
@@ -64233,6 +64388,16 @@ async function calcMotor(args) {
|
|
|
64233
64388
|
fringing_derate: r4(fringing.derate),
|
|
64234
64389
|
fringing_note: "Carter-like first-order derate: B under the pole drops by w/(w+2g) as flux fringes ~one gap length past each pole edge. Kt/Ke and the curve use the DERATED flux. Honest for pole width \u2273 2\xD7 gap; below that treat it as a lower bound."
|
|
64235
64390
|
} : {},
|
|
64391
|
+
...solution?.bToothTesla != null ? {
|
|
64392
|
+
tooth_flux_tesla: r4(solution.bToothTesla),
|
|
64393
|
+
tooth_concentration: r4(solution.toothConcentration ?? 1),
|
|
64394
|
+
// Fringing redistributes flux under the pole; it does not remove
|
|
64395
|
+
// it, so the tooth carries the RAW gap flux either way.
|
|
64396
|
+
tooth_note: "B_tooth = raw B_gap \xB7 (tooth pitch / tooth width) \u2014 the gap flux of a whole tooth pitch funnels into one tooth body. Compare against your steel's knee (~1.5-1.7 T for M19-class silicon steel)."
|
|
64397
|
+
} : {},
|
|
64398
|
+
...solution?.bIronTesla != null ? { yoke_flux_tesla: r4(solution.bIronTesla) } : {},
|
|
64399
|
+
...solution?.nonlinear ? { iron_model: "saturating (arctangent B-H)" } : {},
|
|
64400
|
+
...solution && solution.warnings.length > 0 ? { warnings: solution.warnings } : {},
|
|
64236
64401
|
winding_factor: windingFactor,
|
|
64237
64402
|
kt_nm_per_a: r4(perf.ktNmPerA),
|
|
64238
64403
|
ke_v_s_per_rad: r4(perf.keVSPerRad),
|
|
@@ -64243,7 +64408,7 @@ async function calcMotor(args) {
|
|
|
64243
64408
|
speed_rad_s: r4(p.speedRadS),
|
|
64244
64409
|
torque_nm: r4(p.torqueNm)
|
|
64245
64410
|
})),
|
|
64246
|
-
note:
|
|
64411
|
+
note: "First-order steady-state estimate (no slotting, no losses)" + (fringing ? "; pole-edge fringing derated via magnet.pole_width_mm" : "; pass magnet.pole_width_mm to derate for fringing") + (solution?.nonlinear ? "; iron solved with its saturating B-H law" : "; iron is LINEAR, so Kt is OPTIMISTIC on a machine whose teeth saturate \u2014 " + (solution?.bToothTesla != null ? "see tooth_flux_tesla, and pass magnet.iron_js_t to solve the saturating network" : "pass magnet.slots + tooth_width_mm to see the tooth field")) + ".",
|
|
64247
64412
|
claims
|
|
64248
64413
|
})
|
|
64249
64414
|
}
|
|
@@ -65715,7 +65880,7 @@ async function fixDrc(args) {
|
|
|
65715
65880
|
};
|
|
65716
65881
|
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
65717
65882
|
}
|
|
65718
|
-
var PCB_LAYER_SET, COPPER_LAYERS, COPPER_LAYER_SET, POSITION_TOLERANCE, PIN_SEP, pinKey, createSchematicSchema, docInputProperties, placeComponentsSchema, routeNetsSchema, runDrcSchema, runErcSchema, critiqueRouteSchema, routeDiffPairSchema, lengthMatchTracesSchema, exportGerberSchema, validateForFabSchema, fabPrepSchema, exportKicadSchema, addCoilSchema, boardFromSolidSchema, addCoilArraySchema, windingLayoutSchema, calcImpedanceSchema, sizeImpedanceSchema, sizePdnSchema, calcCoilSchema, sizeCoilSchema, calcRfSchema, COIL_GEOMETRY, MU0, RAIL_PIN_NAMES, PIN_TYPES, CHIP_SIZE_CODES, CONNECTIVITY_GUARD_MAX_NETS, POWER_NET_RE, DRC_CATEGORY, DRC_DELTA_SAMPLE_CAP, DRC_DELTA_FULL_BOARD_MAX, LINT_CRYSTAL_MAX_MM, LINT_DECAP_MAX_MM, LINT_CONNECTOR_EDGE_MAX_MM, LINT_HIGH_CURRENT_SEP_MIN_MM, LINT_GROUND_NET_RE, LINT_SUPPLY_NET_RE, SENSITIVE_NET_RE, HIGH_CURRENT_CLASS_RE, refPrefix, dist2d, round2, sumSq, round33, vec2Schema, setBoardOutlineSchema, FOOTPRINT_FAMILIES, listFootprintsSchema, searchFootprintsSchema, getPadPositionsSchema, getFootprintSchema, ROTATION_CONVENTION, describePcbSchema, DESCRIBE_NET_NAME_CAP, addTraceSchema, addViaSchema, OZ_TO_MM, setStackupSchema, setPlacementSchema, addZoneSchema, deleteElementProps, deleteZoneSchema, deleteTraceSchema, deleteViaSchema, COPPER_KINDS, GET_COPPER_CAP, getCopperSchema, TIE_POSITION_TOL, addNetTieSchema, deleteNetTieSchema, undoSchema, setDesignRulesSchema, sizeTraceForCurrentSchema, addViaArraySchema, MAX_VIA_ARRAY, addMotorWindingSchema, calcMotorSchema, sig6, BEARING_FRICTION_MNM, checkSelfStartSchema, solidFromBoardSchema, FR4_DENSITY_KG_M3, COPPER_DENSITY_KG_M3, DEFAULT_COPPER_THICKNESS_MM, loopArea, MOUNTING_FP_RE, KEEPOUT_ECHO_CAP, INLINE_DOC_ECHO_CAP, searchElectronicPartsSchema, resolvePartSchema, findAlternativesSchema, verifySubstitutionSchema, buildReceiptSchema, verifyReceiptSchema, FIX_EPS, FIX_DRC_NEVER, fixDrcSchema, toolDefs20;
|
|
65883
|
+
var PCB_LAYER_SET, COPPER_LAYERS, COPPER_LAYER_SET, POSITION_TOLERANCE, PIN_SEP, pinKey, createSchematicSchema, docInputProperties, placeComponentsSchema, routeNetsSchema, runDrcSchema, runErcSchema, critiqueRouteSchema, routeDiffPairSchema, lengthMatchTracesSchema, exportGerberSchema, validateForFabSchema, fabPrepSchema, exportKicadSchema, addCoilSchema, boardFromSolidSchema, addCoilArraySchema, windingLayoutSchema, calcImpedanceSchema, sizeImpedanceSchema, sizePdnSchema, calcCoilSchema, sizeCoilSchema, calcRfSchema, COIL_GEOMETRY, MU0, RAIL_PIN_NAMES, PIN_TYPES, CHIP_SIZE_CODES, CONNECTIVITY_GUARD_MAX_NETS, POWER_NET_RE, DRC_CATEGORY, DRC_DELTA_SAMPLE_CAP, DRC_DELTA_FULL_BOARD_MAX, LINT_CRYSTAL_MAX_MM, LINT_DECAP_MAX_MM, LINT_CONNECTOR_EDGE_MAX_MM, LINT_HIGH_CURRENT_SEP_MIN_MM, LINT_GROUND_NET_RE, LINT_SUPPLY_NET_RE, SENSITIVE_NET_RE, HIGH_CURRENT_CLASS_RE, refPrefix, dist2d, round2, sumSq, round33, vec2Schema, setBoardOutlineSchema, FOOTPRINT_FAMILIES, listFootprintsSchema, searchFootprintsSchema, getPadPositionsSchema, getFootprintSchema, ROTATION_CONVENTION, describePcbSchema, DESCRIBE_NET_NAME_CAP, addTraceSchema, addViaSchema, OZ_TO_MM, setStackupSchema, setPlacementSchema, addZoneSchema, deleteElementProps, deleteZoneSchema, deleteTraceSchema, deleteViaSchema, COPPER_KINDS, GET_COPPER_CAP, getCopperSchema, TIE_POSITION_TOL, addNetTieSchema, deleteNetTieSchema, undoSchema, setDesignRulesSchema, sizeTraceForCurrentSchema, addViaArraySchema, MAX_VIA_ARRAY, addMotorWindingSchema, calcMotorSchema, SILICON_STEEL_KNEE_T, sig6, BEARING_FRICTION_MNM, checkSelfStartSchema, solidFromBoardSchema, FR4_DENSITY_KG_M3, COPPER_DENSITY_KG_M3, DEFAULT_COPPER_THICKNESS_MM, loopArea, MOUNTING_FP_RE, KEEPOUT_ECHO_CAP, INLINE_DOC_ECHO_CAP, searchElectronicPartsSchema, resolvePartSchema, findAlternativesSchema, verifySubstitutionSchema, buildReceiptSchema, verifyReceiptSchema, FIX_EPS, FIX_DRC_NEVER, fixDrcSchema, toolDefs20;
|
|
65719
65884
|
var init_ecad2 = __esm({
|
|
65720
65885
|
"src/tools/ecad.ts"() {
|
|
65721
65886
|
"use strict";
|
|
@@ -67127,7 +67292,7 @@ var init_ecad2 = __esm({
|
|
|
67127
67292
|
},
|
|
67128
67293
|
magnet: {
|
|
67129
67294
|
type: "object",
|
|
67130
|
-
description: "PM mode: optional magnet/geometry to compute B_gap when airgap_flux_tesla is omitted (NdFeB defaults). Fields: remanence_tesla, magnet_thickness_mm, airgap_mm, recoil_mu_rel, magnet_area_mm2, gap_area_mm2, iron_mu_rel. Add pole_width_mm (magnet pole face width across the fringing direction) to also apply the first-order Carter-like fringing derate w/(w+2g) \u2014 the tool then reports raw AND derated B and uses the derated value for Kt."
|
|
67295
|
+
description: "PM mode: optional magnet/geometry to compute B_gap when airgap_flux_tesla is omitted (NdFeB defaults). Fields: remanence_tesla, magnet_thickness_mm, airgap_mm, recoil_mu_rel, magnet_area_mm2, gap_area_mm2, iron_mu_rel. Add pole_width_mm (magnet pole face width across the fringing direction) to also apply the first-order Carter-like fringing derate w/(w+2g) \u2014 the tool then reports raw AND derated B and uses the derated value for Kt. SATURATION: the MEC iron is LINEAR unless you say otherwise, so it over-predicts Kt on a machine whose teeth saturate. Pass slots + (tooth_width_mm or tooth_fraction) to make the teeth visible \u2014 the tool then reports tooth_flux_density (B_gap \xB7 pitch/width, routinely 2x B_gap) and warns when it passes the ~1.5 T silicon-steel knee. Add iron_js_t (saturation polarization, silicon steel \u2248 2.0 T) with iron_mu_rel to actually SOLVE the saturating network instead of merely warning; tooth_path_mm puts the teeth in the reluctance loop."
|
|
67131
67296
|
},
|
|
67132
67297
|
phase_current_a: { type: "number", description: "Induction mode (required): phase current, A RMS (balanced 3-phase drive)." },
|
|
67133
67298
|
electrical_freq_hz: { type: "number", description: "Induction mode (required): electrical drive frequency, Hz." },
|
|
@@ -67146,6 +67311,7 @@ var init_ecad2 = __esm({
|
|
|
67146
67311
|
},
|
|
67147
67312
|
required: ["pole_pairs", "turns_per_phase"]
|
|
67148
67313
|
};
|
|
67314
|
+
SILICON_STEEL_KNEE_T = 1.5;
|
|
67149
67315
|
sig6 = (v) => v === 0 || !Number.isFinite(v) ? v : Number(v.toPrecision(6));
|
|
67150
67316
|
BEARING_FRICTION_MNM = {
|
|
67151
67317
|
"608-2RS": {
|
|
@@ -71400,6 +71566,22 @@ var init_em = __esm({
|
|
|
71400
71566
|
type: "number",
|
|
71401
71567
|
description: "SOR sweep cap. Default 200000."
|
|
71402
71568
|
},
|
|
71569
|
+
picard_max_iters: {
|
|
71570
|
+
type: "number",
|
|
71571
|
+
description: "Saturable iron only: cap on the NONLINEAR outer loop over the B-H law. Default 300. Separate from max_sweeps, which caps the inner SOR solve and does nothing for a non-converging material state. A deeply saturated motor section contracts steadily but needs 150-250 iterations; raise this when the error says the residual is still falling."
|
|
71572
|
+
},
|
|
71573
|
+
picard_tol: {
|
|
71574
|
+
type: "number",
|
|
71575
|
+
description: "Saturable iron only: nonlinear convergence tolerance on the largest relative reluctivity update. Default 1e-4. Raise it to accept a looser material state deliberately."
|
|
71576
|
+
},
|
|
71577
|
+
picard_relax: {
|
|
71578
|
+
type: "number",
|
|
71579
|
+
description: "Saturable iron only: under-relaxation of the nonlinear loop, in (0, 1]. Default 0.7. Lower it ONLY when the error reports the residual has stopped falling (a limit cycle); when the residual is still falling, lowering this makes convergence strictly slower \u2014 raise picard_max_iters instead."
|
|
71580
|
+
},
|
|
71581
|
+
picard_adaptive: {
|
|
71582
|
+
type: "boolean",
|
|
71583
|
+
description: "Saturable iron only: back the relaxation off automatically when the nonlinear residual makes no progress over a 10-iteration window. Default FALSE \u2014 on a healthy saturated solve it reacts to ordinary residual jitter and costs ~1.7x the iterations. Turn it on for a device that is demonstrably oscillating."
|
|
71584
|
+
},
|
|
71403
71585
|
drive_coil: {
|
|
71404
71586
|
type: "number",
|
|
71405
71587
|
description: "Axisym: coil index the inductance claim is priced for. Default 0."
|
|
@@ -78869,8 +79051,8 @@ var init_server3 = __esm({
|
|
|
78869
79051
|
init_order_feed();
|
|
78870
79052
|
init_animate();
|
|
78871
79053
|
PKG_VERSION = (() => {
|
|
78872
|
-
if ("0.9.4-main.
|
|
78873
|
-
return "0.9.4-main.
|
|
79054
|
+
if ("0.9.4-main.29") {
|
|
79055
|
+
return "0.9.4-main.29";
|
|
78874
79056
|
}
|
|
78875
79057
|
try {
|
|
78876
79058
|
const req = createRequire2(import.meta.url);
|
|
@@ -78879,8 +79061,8 @@ var init_server3 = __esm({
|
|
|
78879
79061
|
return "0.0.0";
|
|
78880
79062
|
}
|
|
78881
79063
|
})();
|
|
78882
|
-
BUILD_SHA = "
|
|
78883
|
-
BUILD_TIME = "2026-07-
|
|
79064
|
+
BUILD_SHA = "d80a65e336d1c8b8ebf75dd1bebc553b41f7ca93";
|
|
79065
|
+
BUILD_TIME = "2026-07-26T00:45:54.095Z";
|
|
78884
79066
|
SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
|
|
78885
79067
|
VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
|
|
78886
79068
|
INSTANCE_ID = randomUUID6().slice(0, 8);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vcad/mcp",
|
|
3
|
-
"version": "0.9.4-main.
|
|
3
|
+
"version": "0.9.4-main.29",
|
|
4
4
|
"description": "vcad MCP server — parametric CAD + PCB design tools for AI agents (self-contained: bundled server + kernel WASM)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://vcad.io",
|
|
21
21
|
"vcadBuild": {
|
|
22
|
-
"sha": "
|
|
23
|
-
"builtAt": "2026-07-
|
|
22
|
+
"sha": "d80a65e336d1c8b8ebf75dd1bebc553b41f7ca93",
|
|
23
|
+
"builtAt": "2026-07-26T00:45:54.095Z"
|
|
24
24
|
}
|
|
25
25
|
}
|
package/vcad_kernel_wasm_bg.wasm
CHANGED
|
Binary file
|