solidworks-mcp-server 3.0.8 → 3.1.3

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.
Files changed (243) hide show
  1. package/CHANGELOG.md +175 -98
  2. package/LICENSE +20 -20
  3. package/README.md +195 -423
  4. package/dist/adapters/circuit-breaker.d.ts +84 -0
  5. package/dist/adapters/circuit-breaker.d.ts.map +1 -0
  6. package/dist/adapters/circuit-breaker.js +228 -0
  7. package/dist/adapters/circuit-breaker.js.map +1 -0
  8. package/dist/adapters/connection-pool.d.ts +83 -0
  9. package/dist/adapters/connection-pool.d.ts.map +1 -0
  10. package/dist/adapters/connection-pool.js +282 -0
  11. package/dist/adapters/connection-pool.js.map +1 -0
  12. package/dist/adapters/edge-adapter.d.ts +43 -0
  13. package/dist/adapters/edge-adapter.d.ts.map +1 -0
  14. package/dist/adapters/edge-adapter.js +417 -0
  15. package/dist/adapters/edge-adapter.js.map +1 -0
  16. package/dist/adapters/factory.d.ts +60 -0
  17. package/dist/adapters/factory.d.ts.map +1 -0
  18. package/dist/adapters/factory.js +212 -0
  19. package/dist/adapters/factory.js.map +1 -0
  20. package/dist/adapters/feature-complexity-analyzer.d.ts +102 -0
  21. package/dist/adapters/feature-complexity-analyzer.d.ts.map +1 -0
  22. package/dist/adapters/feature-complexity-analyzer.js +322 -0
  23. package/dist/adapters/feature-complexity-analyzer.js.map +1 -0
  24. package/dist/adapters/macro-generator.d.ts +30 -0
  25. package/dist/adapters/macro-generator.d.ts.map +1 -0
  26. package/dist/adapters/macro-generator.js +524 -0
  27. package/dist/adapters/macro-generator.js.map +1 -0
  28. package/dist/adapters/mock-solidworks-adapter.d.ts +92 -0
  29. package/dist/adapters/mock-solidworks-adapter.d.ts.map +1 -0
  30. package/dist/adapters/mock-solidworks-adapter.js +367 -0
  31. package/dist/adapters/mock-solidworks-adapter.js.map +1 -0
  32. package/dist/adapters/types.d.ts +376 -0
  33. package/dist/adapters/types.d.ts.map +1 -0
  34. package/dist/adapters/types.js +261 -0
  35. package/dist/adapters/types.js.map +1 -0
  36. package/dist/adapters/winax-adapter-enhanced.d.ts +55 -0
  37. package/dist/adapters/winax-adapter-enhanced.d.ts.map +1 -0
  38. package/dist/adapters/winax-adapter-enhanced.js +601 -0
  39. package/dist/adapters/winax-adapter-enhanced.js.map +1 -0
  40. package/dist/adapters/winax-adapter.d.ts +55 -0
  41. package/dist/adapters/winax-adapter.d.ts.map +1 -0
  42. package/dist/adapters/winax-adapter.js +667 -0
  43. package/dist/adapters/winax-adapter.js.map +1 -0
  44. package/dist/api/stainless-api.d.ts +29 -0
  45. package/dist/api/stainless-api.d.ts.map +1 -0
  46. package/dist/api/stainless-api.js +408 -0
  47. package/dist/api/stainless-api.js.map +1 -0
  48. package/dist/cache/manager.d.ts.map +1 -1
  49. package/dist/cache/manager.js +4 -3
  50. package/dist/cache/manager.js.map +1 -1
  51. package/dist/core/interfaces/core-abstractions.d.ts.map +1 -1
  52. package/dist/core/interfaces/core-abstractions.js.map +1 -1
  53. package/dist/db/connection.js +4 -4
  54. package/dist/db/connection.js.map +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +86 -79
  57. package/dist/index.js.map +1 -1
  58. package/dist/knowledge/chromadb.d.ts.map +1 -1
  59. package/dist/knowledge/chromadb.js +5 -3
  60. package/dist/knowledge/chromadb.js.map +1 -1
  61. package/dist/macro/recorder.d.ts +1 -1
  62. package/dist/macro/recorder.d.ts.map +1 -1
  63. package/dist/macro/recorder.js +10 -10
  64. package/dist/macro/recorder.js.map +1 -1
  65. package/dist/resources/base.js +10 -10
  66. package/dist/resources/base.js.map +1 -1
  67. package/dist/resources/design-table.d.ts +10 -12
  68. package/dist/resources/design-table.d.ts.map +1 -1
  69. package/dist/resources/design-table.js +42 -39
  70. package/dist/resources/design-table.js.map +1 -1
  71. package/dist/resources/pdm.d.ts +44 -45
  72. package/dist/resources/pdm.d.ts.map +1 -1
  73. package/dist/resources/pdm.js +118 -79
  74. package/dist/resources/pdm.js.map +1 -1
  75. package/dist/resources/registry.d.ts +1 -1
  76. package/dist/resources/registry.d.ts.map +1 -1
  77. package/dist/resources/registry.js +1 -1
  78. package/dist/shared/constants/solidworks-constants.d.ts.map +1 -1
  79. package/dist/shared/constants/solidworks-constants.js +9 -9
  80. package/dist/shared/constants/solidworks-constants.js.map +1 -1
  81. package/dist/solidworks/api.d.ts +8 -6
  82. package/dist/solidworks/api.d.ts.map +1 -1
  83. package/dist/solidworks/api.js +614 -188
  84. package/dist/solidworks/api.js.map +1 -1
  85. package/dist/state/store.d.ts +1 -1
  86. package/dist/state/store.d.ts.map +1 -1
  87. package/dist/state/store.js +14 -14
  88. package/dist/state/store.js.map +1 -1
  89. package/dist/tools/analysis.d.ts +12 -2
  90. package/dist/tools/analysis.d.ts.map +1 -1
  91. package/dist/tools/analysis.js +141 -31
  92. package/dist/tools/analysis.js.map +1 -1
  93. package/dist/tools/diagnostics.d.ts +1 -1
  94. package/dist/tools/diagnostics.d.ts.map +1 -1
  95. package/dist/tools/diagnostics.js +2 -2
  96. package/dist/tools/diagnostics.js.map +1 -1
  97. package/dist/tools/drawing.d.ts +2 -2
  98. package/dist/tools/drawing.d.ts.map +1 -1
  99. package/dist/tools/drawing.js +94 -10
  100. package/dist/tools/drawing.js.map +1 -1
  101. package/dist/tools/enhanced-drawing.d.ts +1 -1
  102. package/dist/tools/enhanced-drawing.d.ts.map +1 -1
  103. package/dist/tools/enhanced-drawing.js +10 -13
  104. package/dist/tools/enhanced-drawing.js.map +1 -1
  105. package/dist/tools/export.d.ts +1 -1
  106. package/dist/tools/export.d.ts.map +1 -1
  107. package/dist/tools/export.js +88 -14
  108. package/dist/tools/export.js.map +1 -1
  109. package/dist/tools/extrusion-helper.d.ts +15 -0
  110. package/dist/tools/extrusion-helper.d.ts.map +1 -0
  111. package/dist/tools/extrusion-helper.js +61 -0
  112. package/dist/tools/extrusion-helper.js.map +1 -0
  113. package/dist/tools/macro-security.d.ts +2 -2
  114. package/dist/tools/macro-security.d.ts.map +1 -1
  115. package/dist/tools/macro-security.js +2 -2
  116. package/dist/tools/macro-security.js.map +1 -1
  117. package/dist/tools/modeling.d.ts +2 -2
  118. package/dist/tools/modeling.d.ts.map +1 -1
  119. package/dist/tools/modeling.js +6 -6
  120. package/dist/tools/modeling.js.map +1 -1
  121. package/dist/tools/native-macro.d.ts +1 -1
  122. package/dist/tools/native-macro.d.ts.map +1 -1
  123. package/dist/tools/native-macro.js +246 -239
  124. package/dist/tools/native-macro.js.map +1 -1
  125. package/dist/tools/sketch.d.ts +28 -28
  126. package/dist/tools/sketch.d.ts.map +1 -1
  127. package/dist/tools/sketch.js +202 -136
  128. package/dist/tools/sketch.js.map +1 -1
  129. package/dist/tools/template-manager.d.ts +5 -5
  130. package/dist/tools/template-manager.d.ts.map +1 -1
  131. package/dist/tools/template-manager.js +66 -65
  132. package/dist/tools/template-manager.js.map +1 -1
  133. package/dist/tools/vba-advanced.d.ts +10 -10
  134. package/dist/tools/vba-advanced.d.ts.map +1 -1
  135. package/dist/tools/vba-advanced.js +791 -708
  136. package/dist/tools/vba-advanced.js.map +1 -1
  137. package/dist/tools/vba-assembly.d.ts +10 -10
  138. package/dist/tools/vba-assembly.d.ts.map +1 -1
  139. package/dist/tools/vba-assembly.js +562 -500
  140. package/dist/tools/vba-assembly.js.map +1 -1
  141. package/dist/tools/vba-drawing.d.ts +12 -12
  142. package/dist/tools/vba-drawing.d.ts.map +1 -1
  143. package/dist/tools/vba-drawing.js +681 -572
  144. package/dist/tools/vba-drawing.js.map +1 -1
  145. package/dist/tools/vba-file-management.d.ts +12 -12
  146. package/dist/tools/vba-file-management.d.ts.map +1 -1
  147. package/dist/tools/vba-file-management.js +662 -589
  148. package/dist/tools/vba-file-management.js.map +1 -1
  149. package/dist/tools/vba-part.d.ts +10 -10
  150. package/dist/tools/vba-part.d.ts.map +1 -1
  151. package/dist/tools/vba-part.js +484 -426
  152. package/dist/tools/vba-part.js.map +1 -1
  153. package/dist/tools/vba.d.ts +361 -361
  154. package/dist/tools/vba.d.ts.map +1 -1
  155. package/dist/tools/vba.js +67 -81
  156. package/dist/tools/vba.js.map +1 -1
  157. package/dist/utils/config.js +2 -2
  158. package/dist/utils/config.js.map +1 -1
  159. package/dist/utils/environment.d.ts +243 -0
  160. package/dist/utils/environment.d.ts.map +1 -0
  161. package/dist/utils/environment.js +207 -0
  162. package/dist/utils/environment.js.map +1 -0
  163. package/dist/utils/logger.d.ts.map +1 -1
  164. package/dist/utils/logger.js +6 -6
  165. package/dist/utils/logger.js.map +1 -1
  166. package/dist/utils/solidworks-config.d.ts +39 -0
  167. package/dist/utils/solidworks-config.d.ts.map +1 -0
  168. package/dist/utils/solidworks-config.js +156 -0
  169. package/dist/utils/solidworks-config.js.map +1 -0
  170. package/package.json +84 -84
  171. package/scripts/setup.js +70 -70
  172. package/dist/application/services/command-bus.d.ts +0 -39
  173. package/dist/application/services/command-bus.d.ts.map +0 -1
  174. package/dist/application/services/command-bus.js +0 -88
  175. package/dist/application/services/command-bus.js.map +0 -1
  176. package/dist/application/services/event-bus.d.ts +0 -31
  177. package/dist/application/services/event-bus.d.ts.map +0 -1
  178. package/dist/application/services/event-bus.js +0 -83
  179. package/dist/application/services/event-bus.js.map +0 -1
  180. package/dist/application/services/query-bus.d.ts +0 -30
  181. package/dist/application/services/query-bus.d.ts.map +0 -1
  182. package/dist/application/services/query-bus.js +0 -59
  183. package/dist/application/services/query-bus.js.map +0 -1
  184. package/dist/application/services/tool-registry.d.ts +0 -53
  185. package/dist/application/services/tool-registry.d.ts.map +0 -1
  186. package/dist/application/services/tool-registry.js +0 -81
  187. package/dist/application/services/tool-registry.js.map +0 -1
  188. package/dist/application/use-cases/analysis/index.d.ts +0 -13
  189. package/dist/application/use-cases/analysis/index.d.ts.map +0 -1
  190. package/dist/application/use-cases/analysis/index.js +0 -17
  191. package/dist/application/use-cases/analysis/index.js.map +0 -1
  192. package/dist/application/use-cases/drawing/index.d.ts +0 -13
  193. package/dist/application/use-cases/drawing/index.d.ts.map +0 -1
  194. package/dist/application/use-cases/drawing/index.js +0 -17
  195. package/dist/application/use-cases/drawing/index.js.map +0 -1
  196. package/dist/application/use-cases/export/index.d.ts +0 -13
  197. package/dist/application/use-cases/export/index.d.ts.map +0 -1
  198. package/dist/application/use-cases/export/index.js +0 -17
  199. package/dist/application/use-cases/export/index.js.map +0 -1
  200. package/dist/application/use-cases/macro/index.d.ts +0 -13
  201. package/dist/application/use-cases/macro/index.d.ts.map +0 -1
  202. package/dist/application/use-cases/macro/index.js +0 -17
  203. package/dist/application/use-cases/macro/index.js.map +0 -1
  204. package/dist/application/use-cases/modeling/index.d.ts +0 -56
  205. package/dist/application/use-cases/modeling/index.d.ts.map +0 -1
  206. package/dist/application/use-cases/modeling/index.js +0 -385
  207. package/dist/application/use-cases/modeling/index.js.map +0 -1
  208. package/dist/index.refactored.d.ts +0 -7
  209. package/dist/index.refactored.d.ts.map +0 -1
  210. package/dist/index.refactored.js +0 -254
  211. package/dist/index.refactored.js.map +0 -1
  212. package/dist/infrastructure/config/configuration-manager.d.ts +0 -381
  213. package/dist/infrastructure/config/configuration-manager.d.ts.map +0 -1
  214. package/dist/infrastructure/config/configuration-manager.js +0 -566
  215. package/dist/infrastructure/config/configuration-manager.js.map +0 -1
  216. package/dist/infrastructure/container/service-locator.d.ts +0 -14
  217. package/dist/infrastructure/container/service-locator.d.ts.map +0 -1
  218. package/dist/infrastructure/container/service-locator.js +0 -38
  219. package/dist/infrastructure/container/service-locator.js.map +0 -1
  220. package/dist/infrastructure/logging/logger.d.ts +0 -24
  221. package/dist/infrastructure/logging/logger.d.ts.map +0 -1
  222. package/dist/infrastructure/logging/logger.js +0 -65
  223. package/dist/infrastructure/logging/logger.js.map +0 -1
  224. package/dist/infrastructure/solidworks/solidworks-adapter.d.ts +0 -43
  225. package/dist/infrastructure/solidworks/solidworks-adapter.d.ts.map +0 -1
  226. package/dist/infrastructure/solidworks/solidworks-adapter.js +0 -527
  227. package/dist/infrastructure/solidworks/solidworks-adapter.js.map +0 -1
  228. package/dist/presentation/mcp/request-handler.d.ts +0 -41
  229. package/dist/presentation/mcp/request-handler.d.ts.map +0 -1
  230. package/dist/presentation/mcp/request-handler.js +0 -100
  231. package/dist/presentation/mcp/request-handler.js.map +0 -1
  232. package/dist/presentation/transformers/error-transformer.d.ts +0 -16
  233. package/dist/presentation/transformers/error-transformer.d.ts.map +0 -1
  234. package/dist/presentation/transformers/error-transformer.js +0 -44
  235. package/dist/presentation/transformers/error-transformer.js.map +0 -1
  236. package/dist/presentation/transformers/response-transformer.d.ts +0 -24
  237. package/dist/presentation/transformers/response-transformer.d.ts.map +0 -1
  238. package/dist/presentation/transformers/response-transformer.js +0 -102
  239. package/dist/presentation/transformers/response-transformer.js.map +0 -1
  240. package/dist/tools/drawing-analysis.d.ts +0 -9
  241. package/dist/tools/drawing-analysis.d.ts.map +0 -1
  242. package/dist/tools/drawing-analysis.js +0 -239
  243. package/dist/tools/drawing-analysis.js.map +0 -1
@@ -1,55 +1,9 @@
1
+ import { mkdirSync, unlinkSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ // @ts-ignore
5
+ import winax from 'winax';
1
6
  import { logger } from '../utils/logger.js';
2
- // @ts-ignore - winax module doesn't have proper TypeScript definitions
3
- // We MUST load winax as CommonJS for it to work properly
4
- let winax;
5
- let ActiveXObject;
6
- // Initialize winax - this MUST happen before we use it
7
- function initializeWinax() {
8
- if (!winax) {
9
- try {
10
- // In the compiled JS, this will use require() which properly loads winax
11
- winax = eval("require('winax')");
12
- ActiveXObject = global.ActiveXObject;
13
- logger.info('Winax initialized successfully', {
14
- hasObject: !!winax?.Object,
15
- hasActiveXObject: !!ActiveXObject
16
- });
17
- }
18
- catch (error) {
19
- logger.error('Failed to initialize winax', error);
20
- throw new Error('Failed to load winax module. Ensure it is installed.');
21
- }
22
- }
23
- return winax;
24
- }
25
- // Create a robust COM object factory
26
- function createCOMObject(progId) {
27
- // Ensure winax is loaded
28
- initializeWinax();
29
- try {
30
- // Method 1: Try winax.Object directly (this worked in your test)
31
- if (winax && winax.Object) {
32
- logger.info(`Creating COM object using winax.Object: ${progId}`);
33
- const obj = new winax.Object(progId);
34
- logger.info(`COM object created successfully`, { progId, hasObject: !!obj });
35
- return obj;
36
- }
37
- // Method 2: Use global ActiveXObject (also worked in your test)
38
- if (ActiveXObject) {
39
- logger.info(`Creating COM object using global ActiveXObject: ${progId}`);
40
- const obj = new ActiveXObject(progId);
41
- logger.info(`COM object created successfully`, { progId, hasObject: !!obj });
42
- return obj;
43
- }
44
- throw new Error('No COM object creation method available');
45
- }
46
- catch (error) {
47
- logger.error(`Failed to create COM object ${progId}:`, error);
48
- throw error;
49
- }
50
- }
51
- // Export a compatibility function for legacy code
52
- export const createActiveXObject = createCOMObject;
53
7
  export class SolidWorksAPI {
54
8
  swApp;
55
9
  currentModel;
@@ -60,13 +14,23 @@ export class SolidWorksAPI {
60
14
  connect() {
61
15
  try {
62
16
  // Create or get running instance of SolidWorks
63
- // Use our robust COM object factory
64
- this.swApp = createCOMObject('SldWorks.Application');
17
+ // @ts-ignore
18
+ this.swApp = new winax.Object('SldWorks.Application');
65
19
  this.swApp.Visible = true;
66
20
  logger.info('Connected to SolidWorks');
67
21
  }
68
- catch (error) {
69
- throw new Error(`Failed to connect to SolidWorks: ${error}`);
22
+ catch (_error) {
23
+ // Try alternative connection method
24
+ try {
25
+ // @ts-ignore
26
+ this.swApp = winax.Object('SldWorks.Application');
27
+ this.swApp.Visible = true;
28
+ logger.info('Connected to SolidWorks (alternative method)');
29
+ }
30
+ catch (error2) {
31
+ logger.error('Failed to connect to SolidWorks', error2);
32
+ throw new Error(`Failed to connect to SolidWorks: ${error2}`);
33
+ }
70
34
  }
71
35
  }
72
36
  disconnect() {
@@ -99,9 +63,16 @@ export class SolidWorksAPI {
99
63
  if (!this.currentModel) {
100
64
  throw new Error(`Failed to open model: ${filePath}`);
101
65
  }
66
+ // Ensure the opened model is set as active
67
+ try {
68
+ this.swApp.ActivateDoc2(this.currentModel.GetTitle(), false, errors);
69
+ }
70
+ catch (_e) {
71
+ // ActivateDoc2 might fail but model is still open
72
+ }
102
73
  return {
103
74
  path: filePath,
104
- name: this.currentModel.GetTitle,
75
+ name: this.currentModel.GetTitle(),
105
76
  type: ['Part', 'Assembly', 'Drawing'][docType - 1],
106
77
  isActive: true,
107
78
  };
@@ -112,14 +83,14 @@ export class SolidWorksAPI {
112
83
  let modelTitle = '';
113
84
  try {
114
85
  // Safely get the title
115
- if ('GetTitle' in this.currentModel) {
116
- modelTitle = this.currentModel.GetTitle;
86
+ if (this.currentModel.GetTitle) {
87
+ modelTitle = this.currentModel.GetTitle();
117
88
  }
118
- else if ('GetPathName' in this.currentModel) {
119
- modelTitle = this.currentModel.GetPathName;
89
+ else if (this.currentModel.GetPathName) {
90
+ modelTitle = this.currentModel.GetPathName();
120
91
  }
121
92
  }
122
- catch (e) {
93
+ catch (_e) {
123
94
  // If we can't get the title, continue anyway
124
95
  modelTitle = 'Unknown';
125
96
  }
@@ -127,13 +98,13 @@ export class SolidWorksAPI {
127
98
  try {
128
99
  this.currentModel.Save3(1, 0, 0); // swSaveAsOptions_Silent
129
100
  }
130
- catch (e) {
101
+ catch (_e) {
131
102
  // Save might fail if document is new and has no path
132
103
  try {
133
104
  // Try Save instead
134
105
  this.currentModel.Save();
135
106
  }
136
- catch (e2) {
107
+ catch (_e2) {
137
108
  // Continue even if save fails
138
109
  }
139
110
  }
@@ -143,7 +114,7 @@ export class SolidWorksAPI {
143
114
  try {
144
115
  this.swApp.CloseDoc(modelTitle);
145
116
  }
146
- catch (e) {
117
+ catch (_e) {
147
118
  // Fallback: just clear the reference
148
119
  }
149
120
  }
@@ -206,7 +177,7 @@ export class SolidWorksAPI {
206
177
  return { success: false, error: 'Failed to create extrusion' };
207
178
  }
208
179
  // Feature operations
209
- createExtrude(depth, draft = 0, reverse = false) {
180
+ createExtrude(depth, _draft = 0, reverse = false) {
210
181
  if (!this.currentModel)
211
182
  throw new Error('No model open');
212
183
  try {
@@ -215,63 +186,200 @@ export class SolidWorksAPI {
215
186
  if (!featureMgr) {
216
187
  throw new Error('Cannot access FeatureManager');
217
188
  }
218
- // Try different extrusion methods based on what's available
189
+ // Make sure we're not in sketch edit mode
190
+ try {
191
+ const sketchMgr = this.currentModel.SketchManager;
192
+ const activeSketch = sketchMgr.ActiveSketch;
193
+ if (activeSketch) {
194
+ // Exit sketch mode
195
+ sketchMgr.InsertSketch(true);
196
+ }
197
+ }
198
+ catch (_e) {
199
+ // Continue if no active sketch
200
+ }
201
+ // Clear selections first
202
+ try {
203
+ this.currentModel.ClearSelection2(true);
204
+ }
205
+ catch (_e) {
206
+ // Continue
207
+ }
208
+ // Select the sketch - try multiple methods with detailed logging
209
+ let sketchSelected = false;
210
+ let selectedSketchName = '';
211
+ const attemptedSketches = [];
212
+ // Method 1 (most reliable): Feature tree traversal
213
+ // This avoids SelectByID2 COM type mismatch issues entirely
214
+ try {
215
+ const featureCount = this.currentModel.GetFeatureCount();
216
+ logger.info(`Searching ${featureCount} features for sketch...`);
217
+ for (let i = 0; i < Math.min(10, featureCount); i++) {
218
+ const feat = this.currentModel.FeatureByPositionReverse(i);
219
+ if (feat) {
220
+ const typeName = feat.GetTypeName2();
221
+ const featName = feat.Name || feat.GetName();
222
+ if (typeName === 'ProfileFeature' || typeName?.toLowerCase().includes('sketch')) {
223
+ feat.Select2(false, 0);
224
+ sketchSelected = true;
225
+ selectedSketchName = featName || `Feature at position ${i}`;
226
+ logger.info(`Selected sketch by feature tree: ${selectedSketchName}`);
227
+ break;
228
+ }
229
+ }
230
+ }
231
+ }
232
+ catch (e) {
233
+ logger.warn(`Feature tree search failed: ${e}`);
234
+ }
235
+ // Method 2 (fallback): SelectByID2 with undefined for optional params
236
+ if (!sketchSelected) {
237
+ const sketchNames = ['Sketch1', 'Sketch2', 'Sketch3', 'Sketch4', 'Sketch5'];
238
+ for (const name of sketchNames) {
239
+ try {
240
+ const ext = this.currentModel.Extension;
241
+ if (ext) {
242
+ const selected = ext.SelectByID2(name, 'SKETCH', 0, 0, 0, false, 0, undefined, 0);
243
+ if (selected) {
244
+ sketchSelected = true;
245
+ selectedSketchName = name;
246
+ logger.info(`Selected sketch via SelectByID2: ${name}`);
247
+ break;
248
+ }
249
+ else {
250
+ attemptedSketches.push(name);
251
+ }
252
+ }
253
+ }
254
+ catch (e) {
255
+ attemptedSketches.push(`${name} (error: ${e})`);
256
+ }
257
+ }
258
+ }
259
+ if (!sketchSelected) {
260
+ const errorMessage = `No sketch found to extrude. Attempted sketches: ${attemptedSketches.join(', ')}. ` +
261
+ `Please ensure a sketch exists or specify the sketch name explicitly.`;
262
+ logger.error(errorMessage);
263
+ throw new Error(errorMessage);
264
+ }
265
+ logger.info(`Using sketch: ${selectedSketchName}`);
266
+ // Convert depth to meters
267
+ const depthInMeters = depth / 1000;
219
268
  let feature = null;
269
+ // Try different extrusion methods
270
+ // The winax library has issues with methods that have many parameters
271
+ // We'll try to use a workaround by creating a variant array
220
272
  try {
221
- // Method 1: Try FeatureExtrusion3 with all parameters
222
- feature = featureMgr.FeatureExtrusion3(true, // SingleEndedFeature
223
- reverse, // ReverseDirection
224
- false, // UseDirection2
225
- 0, // EndCondition1 (0 = blind)
226
- 0, // EndCondition2
227
- depth / 1000, // Depth1 (convert mm to m)
228
- 0.01, // Depth2
229
- false, // RevOffset1
230
- false, // RevOffset2
231
- false, // ThinFeature
232
- draft * Math.PI / 180, // DraftAngle1 (convert to radians)
233
- 0, // DraftAngle2
234
- false, // DraftOutward1
235
- false, // DraftOutward2
236
- false, // DraftWhileDrag1
237
- false, // DraftWhileDrag2
238
- false, // ReverseOffset1Dir
239
- true, // TranslateSurface1
240
- false, // NormalToCurve
241
- 0, // StartCondition
242
- 0, // SketchPlane
243
- false // FlipStartDirection
244
- );
273
+ // Method 1: Try the basic FeatureExtrusion with minimal params
274
+ // This uses a different calling convention that might work better
275
+ const args = [
276
+ true, // Sd (single direction)
277
+ reverse, // Flip
278
+ false, // Dir
279
+ 0, // T1 (0 = blind)
280
+ 0, // T2
281
+ depthInMeters, // D1 (depth)
282
+ 0, // D2
283
+ false, // Dchk1
284
+ false, // Dchk2
285
+ false, // Ddir1
286
+ false, // Ddir2
287
+ 0, // Dang1
288
+ 0, // Dang2
289
+ ];
290
+ // Try to invoke the method directly
291
+ feature = featureMgr.FeatureExtrusion.apply(featureMgr, args);
292
+ logger.info('FeatureExtrusion succeeded with apply');
245
293
  }
246
294
  catch (e) {
247
- // Method 2: Try FeatureExtrusion2 with fewer parameters
295
+ logger.warn(`FeatureExtrusion with apply failed: ${e}`);
296
+ // Method 2: Try using the __methods__ property if available
248
297
  try {
249
- feature = featureMgr.FeatureExtrusion2(true, // SingleEndedFeature
250
- reverse, // ReverseDirection
251
- false, // UseDirection2
252
- 0, // EndCondition1
253
- 0, // EndCondition2
254
- depth / 1000, // Depth1
255
- 0.01, // Depth2
256
- false, // RevOffset1
257
- false, // RevOffset2
258
- false, // ThinFeature
259
- draft * Math.PI / 180, // DraftAngle1
260
- 0, // DraftAngle2
261
- false, // DraftOutward1
262
- false // DraftOutward2
263
- );
298
+ // Some COM objects expose methods differently
299
+ if (featureMgr.__methods__?.FeatureExtrusion) {
300
+ feature = featureMgr.__methods__.FeatureExtrusion(true, reverse, false, 0, 0, depthInMeters, 0, false, false, false, false, 0, 0);
301
+ logger.info('FeatureExtrusion succeeded via __methods__');
302
+ }
303
+ else {
304
+ throw new Error('__methods__ not available');
305
+ }
264
306
  }
265
307
  catch (e2) {
266
- // Method 3: Try the simplest FeatureExtrusion
267
- feature = featureMgr.FeatureExtrusion(true, reverse, 0, depth / 1000, 0, 0, true, false, false, draft * Math.PI / 180, 0, false, false);
308
+ logger.warn(`Alternative method failed: ${e2}`);
309
+ // Method 3: Try to create the extrusion using automation-compatible approach
310
+ try {
311
+ // Last resort: Try with explicit VARIANT conversion if available
312
+ const variant = winax.Variant;
313
+ if (variant) {
314
+ const params = new variant([
315
+ true,
316
+ reverse,
317
+ false,
318
+ 0,
319
+ 0,
320
+ depthInMeters,
321
+ 0,
322
+ false,
323
+ false,
324
+ false,
325
+ false,
326
+ 0,
327
+ 0,
328
+ ]);
329
+ feature = featureMgr.FeatureExtrusion(params);
330
+ logger.info('FeatureExtrusion succeeded with VARIANT');
331
+ }
332
+ else {
333
+ // Final fallback: standard call
334
+ feature = featureMgr.FeatureExtrusion(true, reverse, false, 0, 0, depthInMeters, 0, false, false, false, false, 0, 0);
335
+ logger.info('FeatureExtrusion succeeded with standard call');
336
+ }
337
+ }
338
+ catch (e3) {
339
+ logger.warn(`All direct COM extrusion methods failed: ${e3}`);
340
+ logger.info('Falling back to VBA macro execution for extrusion...');
341
+ // Method 4: VBA macro fallback - bypasses winax parameter limit
342
+ feature = this.executeExtrusionViaMacro(depthInMeters, reverse);
343
+ }
268
344
  }
269
345
  }
270
346
  if (!feature) {
271
- throw new Error('Failed to create extrusion - ensure a sketch is selected');
347
+ throw new Error('Failed to create extrusion - feature is null');
348
+ }
349
+ // Get feature name
350
+ let featureName = 'Boss-Extrude1';
351
+ try {
352
+ if (feature.Name) {
353
+ featureName = feature.Name;
354
+ }
355
+ else if (feature.GetName) {
356
+ featureName = feature.GetName();
357
+ }
358
+ }
359
+ catch (_e) {
360
+ // Use default name
361
+ }
362
+ // Clear selections
363
+ try {
364
+ this.currentModel.ClearSelection2(true);
365
+ }
366
+ catch (_e) {
367
+ // Ignore
368
+ }
369
+ // Rebuild
370
+ try {
371
+ this.currentModel.EditRebuild3();
372
+ }
373
+ catch (_e) {
374
+ try {
375
+ this.currentModel.EditRebuild();
376
+ }
377
+ catch (_e2) {
378
+ // Continue
379
+ }
272
380
  }
273
381
  return {
274
- name: feature.Name,
382
+ name: featureName,
275
383
  type: 'Extrusion',
276
384
  suppressed: false,
277
385
  };
@@ -280,24 +388,288 @@ export class SolidWorksAPI {
280
388
  throw new Error(`Extrusion failed: ${error}`);
281
389
  }
282
390
  }
391
+ /**
392
+ * Execute extrusion via VBA macro - bypasses winax COM parameter limit.
393
+ * Used as fallback when direct COM calls fail with type mismatch errors.
394
+ */
395
+ executeExtrusionViaMacro(depthInMeters, reverse) {
396
+ const macroDir = join(tmpdir(), 'solidworks-mcp-macros');
397
+ const macroPath = join(macroDir, `extrusion_${Date.now()}.swp`);
398
+ try {
399
+ mkdirSync(macroDir, { recursive: true });
400
+ }
401
+ catch (_e) {
402
+ // Directory may already exist
403
+ }
404
+ // Generate a silent VBA macro (no MsgBox — automation-safe)
405
+ const vbaCode = `Attribute VB_Name = "Module1"
406
+ Option Explicit
407
+
408
+ Sub CreateExtrusion()
409
+ Dim swApp As Object
410
+ Dim swModel As Object
411
+ Dim swFeatureMgr As Object
412
+ Dim swFeature As Object
413
+
414
+ On Error GoTo ErrorHandler
415
+
416
+ Set swApp = Application.SldWorks
417
+ Set swModel = swApp.ActiveDoc
418
+
419
+ If swModel Is Nothing Then Exit Sub
420
+
421
+ Set swFeatureMgr = swModel.FeatureManager
422
+
423
+ ' The sketch should already be selected by the caller.
424
+ ' Create a simple blind extrusion using FeatureExtrusion3
425
+ Set swFeature = swFeatureMgr.FeatureExtrusion3( _
426
+ True, _ ' Sd (single direction)
427
+ ${reverse ? 'True' : 'False'}, _ ' Flip
428
+ False, _ ' Dir (both directions)
429
+ 0, _ ' T1 (blind end condition)
430
+ 0, _ ' T2
431
+ ${depthInMeters}, _ ' D1 (depth in meters)
432
+ 0, _ ' D2
433
+ False, _ ' Dchk1 (draft while extruding)
434
+ False, _ ' Dchk2
435
+ False, _ ' Ddir1 (draft outward)
436
+ False, _ ' Ddir2
437
+ 0, _ ' Dang1 (draft angle)
438
+ 0, _ ' Dang2
439
+ False, _ ' OffsetReverse1
440
+ False, _ ' OffsetReverse2
441
+ False, _ ' TranslateSurface1
442
+ False, _ ' TranslateSurface2
443
+ True, _ ' Merge
444
+ False, _ ' FlipSideToCut
445
+ True, _ ' UseFeatScope
446
+ 0, _ ' StartCondition
447
+ 0, _ ' StartOffset
448
+ False _ ' FlipStartOffset
449
+ )
450
+
451
+ ' Rebuild the model
452
+ swModel.EditRebuild3
453
+
454
+ Exit Sub
455
+
456
+ ErrorHandler:
457
+ ' Silent fail — caller checks for feature creation
458
+ Debug.Print "Extrusion macro error: " & Err.Description
459
+ End Sub
460
+ `;
461
+ try {
462
+ writeFileSync(macroPath, vbaCode, 'utf-8');
463
+ logger.info(`Wrote extrusion macro to ${macroPath}`);
464
+ // Execute the macro via SolidWorks RunMacro2
465
+ const runResult = this.swApp.RunMacro2(macroPath, 'Module1', 'CreateExtrusion', 1, // swRunMacroOption_e.swRunMacroUnloadAfterRun
466
+ 0 // error out param
467
+ );
468
+ logger.info(`RunMacro2 returned: ${runResult}`);
469
+ // Retrieve the newly created feature (should be the most recent)
470
+ const feature = this.currentModel.FeatureByPositionReverse(0);
471
+ if (feature) {
472
+ const typeName = feature.GetTypeName2?.() || '';
473
+ if (typeName.toLowerCase().includes('extrusion') || typeName.toLowerCase().includes('boss')) {
474
+ logger.info(`VBA macro extrusion succeeded: ${feature.Name || feature.GetName?.()}`);
475
+ return feature;
476
+ }
477
+ }
478
+ throw new Error('VBA macro executed but no extrusion feature found');
479
+ }
480
+ catch (macroError) {
481
+ logger.error(`VBA macro extrusion failed: ${macroError}`);
482
+ throw new Error(`Extrusion failed: all direct COM methods and VBA macro fallback failed. Details: ${macroError}`);
483
+ }
484
+ finally {
485
+ // Clean up temp macro file
486
+ try {
487
+ unlinkSync(macroPath);
488
+ }
489
+ catch (_e) {
490
+ // Ignore cleanup errors
491
+ }
492
+ }
493
+ }
283
494
  // Dimension operations
284
495
  getDimension(name) {
285
496
  if (!this.currentModel)
286
497
  throw new Error('No model open');
287
- const dimension = this.currentModel.Parameter(name);
498
+ let dimension = null;
499
+ // Method 1: Try Parameter method
500
+ try {
501
+ dimension = this.currentModel.Parameter(name);
502
+ }
503
+ catch (_e) {
504
+ // Parameter might not work
505
+ }
506
+ // Method 2: Try GetParameter
288
507
  if (!dimension) {
289
- throw new Error(`Dimension "${name}" not found`);
508
+ try {
509
+ dimension = this.currentModel.GetParameter(name);
510
+ }
511
+ catch (_e) {
512
+ // GetParameter might not work
513
+ }
514
+ }
515
+ // Method 3: Try Extension.GetParameter
516
+ if (!dimension) {
517
+ try {
518
+ const ext = this.currentModel.Extension;
519
+ if (ext) {
520
+ dimension = ext.GetParameter(name);
521
+ }
522
+ }
523
+ catch (_e) {
524
+ // Extension method might not work
525
+ }
526
+ }
527
+ // Method 4: Try SelectByID and get dimension
528
+ if (!dimension) {
529
+ try {
530
+ const selected = this.currentModel.Extension.SelectByID2(name, 'DIMENSION', 0, 0, 0, false, 0, undefined, 0);
531
+ if (selected) {
532
+ const selMgr = this.currentModel.SelectionManager;
533
+ if (selMgr && selMgr.GetSelectedObjectCount() > 0) {
534
+ const obj = selMgr.GetSelectedObject6(1, -1);
535
+ if (obj) {
536
+ dimension = obj;
537
+ }
538
+ }
539
+ this.currentModel.ClearSelection2(true);
540
+ }
541
+ }
542
+ catch (_e) {
543
+ // Selection method failed
544
+ }
545
+ }
546
+ if (!dimension) {
547
+ throw new Error(`Dimension "${name}" not found. Try format like "D1@Sketch1" or "D1@Boss-Extrude1"`);
548
+ }
549
+ // Get the value - try different properties
550
+ let value = 0;
551
+ try {
552
+ if (dimension.SystemValue !== undefined) {
553
+ value = dimension.SystemValue * 1000; // Convert m to mm
554
+ }
555
+ else if (dimension.Value !== undefined) {
556
+ value = dimension.Value * 1000;
557
+ }
558
+ else if (dimension.GetSystemValue) {
559
+ value = dimension.GetSystemValue() * 1000;
560
+ }
561
+ else {
562
+ throw new Error('Cannot read dimension value');
563
+ }
564
+ }
565
+ catch (_e) {
566
+ throw new Error(`Cannot read value of dimension "${name}"`);
290
567
  }
291
- return dimension.SystemValue * 1000; // Convert m to mm
568
+ return value;
292
569
  }
293
570
  setDimension(name, value) {
294
571
  if (!this.currentModel)
295
572
  throw new Error('No model open');
296
- const dimension = this.currentModel.Parameter(name);
573
+ let dimension = null;
574
+ // Method 1: Try Parameter method
575
+ try {
576
+ dimension = this.currentModel.Parameter(name);
577
+ }
578
+ catch (_e) {
579
+ // Parameter might not work
580
+ }
581
+ // Method 2: Try GetParameter
582
+ if (!dimension) {
583
+ try {
584
+ dimension = this.currentModel.GetParameter(name);
585
+ }
586
+ catch (_e) {
587
+ // GetParameter might not work
588
+ }
589
+ }
590
+ // Method 3: Try Extension.GetParameter
591
+ if (!dimension) {
592
+ try {
593
+ const ext = this.currentModel.Extension;
594
+ if (ext) {
595
+ dimension = ext.GetParameter(name);
596
+ }
597
+ }
598
+ catch (_e) {
599
+ // Extension method might not work
600
+ }
601
+ }
602
+ // Method 4: Try SelectByID and get dimension
603
+ if (!dimension) {
604
+ try {
605
+ const selected = this.currentModel.Extension.SelectByID2(name, 'DIMENSION', 0, 0, 0, false, 0, undefined, 0);
606
+ if (selected) {
607
+ const selMgr = this.currentModel.SelectionManager;
608
+ if (selMgr && selMgr.GetSelectedObjectCount() > 0) {
609
+ const obj = selMgr.GetSelectedObject6(1, -1);
610
+ if (obj) {
611
+ dimension = obj;
612
+ }
613
+ }
614
+ // Don't clear selection yet - might need it for setting
615
+ }
616
+ }
617
+ catch (_e) {
618
+ // Selection method failed
619
+ }
620
+ }
297
621
  if (!dimension) {
298
- throw new Error(`Dimension "${name}" not found`);
622
+ throw new Error(`Dimension "${name}" not found. Try format like "D1@Sketch1" or "D1@Boss-Extrude1"`);
623
+ }
624
+ // Set the value - try different methods
625
+ const newValue = value / 1000; // Convert mm to m
626
+ let success = false;
627
+ try {
628
+ if (dimension.SystemValue !== undefined) {
629
+ dimension.SystemValue = newValue;
630
+ success = true;
631
+ }
632
+ else if (dimension.Value !== undefined) {
633
+ dimension.Value = newValue;
634
+ success = true;
635
+ }
636
+ else if (dimension.SetSystemValue) {
637
+ success = dimension.SetSystemValue(newValue);
638
+ }
639
+ else if (dimension.SetValue) {
640
+ success = dimension.SetValue(newValue);
641
+ }
642
+ }
643
+ catch (_e) {
644
+ // Try equation manager
645
+ try {
646
+ const eqMgr = this.currentModel.GetEquationMgr();
647
+ if (eqMgr) {
648
+ const count = eqMgr.GetCount();
649
+ for (let i = 0; i < count; i++) {
650
+ const eq = eqMgr.Equation[i];
651
+ if (eq?.includes(name)) {
652
+ eqMgr.Equation[i] = `"${name}" = ${value}`;
653
+ success = true;
654
+ break;
655
+ }
656
+ }
657
+ }
658
+ }
659
+ catch (_e2) {
660
+ // Equation manager failed
661
+ }
662
+ }
663
+ // Clear selection if we used it
664
+ try {
665
+ this.currentModel.ClearSelection2(true);
666
+ }
667
+ catch (_e) {
668
+ // Ignore clear selection errors
669
+ }
670
+ if (!success) {
671
+ throw new Error(`Failed to set dimension "${name}" to ${value}mm`);
299
672
  }
300
- dimension.SystemValue = value / 1000; // Convert mm to m
301
673
  this.currentModel.EditRebuild3();
302
674
  }
303
675
  // Export operations
@@ -306,100 +678,114 @@ export class SolidWorksAPI {
306
678
  throw new Error('No model open');
307
679
  try {
308
680
  // Ensure the model is saved first
309
- const currentPath = this.currentModel.GetPathName;
681
+ const currentPath = this.currentModel.GetPathName();
310
682
  if (!currentPath || currentPath === '') {
311
683
  // Save the model first if it hasn't been saved
312
- const docType = this.currentModel.GetType;
684
+ const docType = this.currentModel.GetType();
313
685
  const ext = docType === 1 ? '.SLDPRT' : docType === 2 ? '.SLDASM' : '.SLDDRW';
314
686
  const tempPath = filePath.replace(/\.[^.]+$/, ext);
315
687
  this.currentModel.SaveAs3(tempPath, 0, 1);
316
688
  }
317
689
  const ext = format.toLowerCase();
318
690
  let success = false;
319
- // Try to get export data
320
- let exportData = null;
321
- try {
322
- exportData = this.swApp.GetExportFileData(1); // 1 = current config only
323
- }
324
- catch (e) {
325
- // Export data might not be available for all formats
326
- }
691
+ const errors = 0;
692
+ const warnings = 0;
693
+ // Try different export methods based on format
327
694
  switch (ext) {
328
695
  case 'step':
329
696
  case 'stp':
330
- if (exportData) {
697
+ // Method 1: Try SaveAs3 with proper file extension
698
+ try {
699
+ success = this.currentModel.SaveAs3(filePath, 0, 2);
700
+ if (!success) {
701
+ // Method 2: Try Extension.SaveAs with swSaveAsCurrentVersion flag
702
+ success = this.currentModel.Extension.SaveAs(filePath, 0, 2, undefined, errors, warnings);
703
+ }
704
+ }
705
+ catch (_e) {
706
+ // Method 3: Try GetExportFileData approach
331
707
  try {
332
- exportData.SetStep203(true); // Use STEP AP203
708
+ const exportData = this.swApp.GetExportFileData(1);
709
+ if (exportData) {
710
+ exportData.SetStep203(true);
711
+ success = this.currentModel.Extension.SaveAs(filePath, 0, 2, exportData, errors, warnings);
712
+ }
333
713
  }
334
- catch (e) {
335
- // Method might not exist
714
+ catch (e2) {
715
+ throw new Error(`Failed to export to STEP: ${e2}`);
336
716
  }
337
717
  }
338
- // Try Extension.SaveAs first
718
+ break;
719
+ case 'iges':
720
+ case 'igs':
721
+ // Method 1: Try SaveAs3 with proper flags
339
722
  try {
340
- success = this.currentModel.Extension.SaveAs(filePath, 0, // version
341
- 1, // options
342
- exportData, 0, // errors
343
- 0 // warnings
344
- );
723
+ success = this.currentModel.SaveAs3(filePath, 0, 2);
724
+ if (!success) {
725
+ // Method 2: Try Extension.SaveAs
726
+ success = this.currentModel.Extension.SaveAs(filePath, 0, 2, undefined, errors, warnings);
727
+ }
345
728
  }
346
729
  catch (e) {
347
- // Fall back to SaveAs3
348
- success = this.currentModel.SaveAs3(filePath, 0, 1);
730
+ throw new Error(`Failed to export to IGES: ${e}`);
349
731
  }
350
732
  break;
351
- case 'iges':
352
- case 'igs':
353
- success = this.currentModel.SaveAs3(filePath, 0, 1);
354
- break;
355
733
  case 'stl':
356
- // STL specific - try SaveAs4 for STL options
734
+ // STL specific - try different methods
357
735
  try {
358
- success = this.currentModel.SaveAs4(filePath, 0, // Version
359
- 1, // Options
360
- 0, // Errors
361
- 0 // Warnings
362
- );
736
+ // Method 1: SaveAs3 with proper flags
737
+ success = this.currentModel.SaveAs3(filePath, 0, 2);
738
+ if (!success) {
739
+ // Method 2: Try SaveAs4 if available
740
+ try {
741
+ success = this.currentModel.SaveAs4(filePath, 0, 2, errors, warnings);
742
+ }
743
+ catch (_e2) {
744
+ // Method 3: Try Extension.SaveAs
745
+ success = this.currentModel.Extension.SaveAs(filePath, 0, 2, undefined, errors, warnings);
746
+ }
747
+ }
363
748
  }
364
749
  catch (e) {
365
- success = this.currentModel.SaveAs3(filePath, 0, 1);
750
+ throw new Error(`Failed to export to STL: ${e}`);
366
751
  }
367
752
  break;
368
- case 'pdf':
753
+ case 'pdf': {
369
754
  // PDF export requires drawing
370
755
  const docType = this.currentModel.GetType();
371
- if (docType !== 3) { // 3 = swDocDRAWING
756
+ if (docType !== 3) {
757
+ // 3 = swDocDRAWING
372
758
  throw new Error('PDF export requires a drawing document');
373
759
  }
374
- // Try ExportPdfData if available
375
760
  try {
376
- const pdfData = this.swApp.GetExportFileData(1);
377
- success = this.currentModel.SaveAs3(filePath, 0, 1);
761
+ success = this.currentModel.SaveAs3(filePath, 0, 2);
762
+ if (!success) {
763
+ success = this.currentModel.Extension.SaveAs(filePath, 0, 2, undefined, errors, warnings);
764
+ }
378
765
  }
379
766
  catch (e) {
380
- success = this.currentModel.SaveAs3(filePath, 0, 1);
767
+ throw new Error(`Failed to export to PDF: ${e}`);
381
768
  }
382
769
  break;
770
+ }
383
771
  case 'dxf':
384
772
  case 'dwg':
385
- // DXF/DWG export
386
- success = this.currentModel.SaveAs3(filePath, 0, 1);
773
+ // DXF/DWG export - mainly for drawings
774
+ try {
775
+ success = this.currentModel.SaveAs3(filePath, 0, 2);
776
+ if (!success) {
777
+ success = this.currentModel.Extension.SaveAs(filePath, 0, 2, undefined, errors, warnings);
778
+ }
779
+ }
780
+ catch (e) {
781
+ throw new Error(`Failed to export to ${format.toUpperCase()}: ${e}`);
782
+ }
387
783
  break;
388
784
  default:
389
- // Try generic export
390
- success = this.currentModel.SaveAs3(filePath, 0, 1);
391
- }
392
- if (!success) {
393
- // Try one more time with SaveAs2
394
- try {
395
- success = this.currentModel.SaveAs2(filePath, 0, true, false);
396
- }
397
- catch (e) {
398
- throw new Error(`Failed to export to ${format}`);
399
- }
785
+ throw new Error(`Unsupported export format: ${format}`);
400
786
  }
401
787
  if (!success) {
402
- throw new Error(`Failed to export to ${format}`);
788
+ throw new Error(`Failed to export to ${format.toUpperCase()}: Export returned false`);
403
789
  }
404
790
  }
405
791
  catch (error) {
@@ -407,7 +793,7 @@ export class SolidWorksAPI {
407
793
  }
408
794
  }
409
795
  // VBA operations
410
- runMacro(macroPath, moduleName, procedureName, args = []) {
796
+ runMacro(macroPath, moduleName, procedureName, _args = []) {
411
797
  if (!this.swApp)
412
798
  throw new Error('Not connected to SolidWorks');
413
799
  const result = this.swApp.RunMacro2(macroPath, moduleName, procedureName, 1, // swRunMacroOption
@@ -421,8 +807,9 @@ export class SolidWorksAPI {
421
807
  if (!this.currentModel)
422
808
  throw new Error('No model open');
423
809
  // Check document type - mass properties only work for parts and assemblies
424
- const docType = this.currentModel.GetType;
425
- if (docType !== 1 && docType !== 2) { // 1=Part, 2=Assembly
810
+ const docType = this.currentModel.GetType();
811
+ if (docType !== 1 && docType !== 2) {
812
+ // 1=Part, 2=Assembly
426
813
  throw new Error('Mass properties only available for parts and assemblies');
427
814
  }
428
815
  try {
@@ -437,12 +824,12 @@ export class SolidWorksAPI {
437
824
  // Method 1: Try CreateMassProperty
438
825
  massProps = modeler.CreateMassProperty();
439
826
  }
440
- catch (e) {
827
+ catch (_e) {
441
828
  // Method 2: Try CreateMassProperty2
442
829
  try {
443
830
  massProps = modeler.CreateMassProperty2();
444
831
  }
445
- catch (e2) {
832
+ catch (_e2) {
446
833
  // Method 3: Try getting it from the model directly
447
834
  massProps = this.currentModel.GetMassProperties();
448
835
  }
@@ -462,7 +849,7 @@ export class SolidWorksAPI {
462
849
  }
463
850
  }
464
851
  }
465
- catch (e) {
852
+ catch (_e) {
466
853
  // Update might not be needed
467
854
  }
468
855
  // Get the values with error handling
@@ -470,19 +857,19 @@ export class SolidWorksAPI {
470
857
  try {
471
858
  result.mass = massProps.Mass;
472
859
  }
473
- catch (e) {
860
+ catch (_e) {
474
861
  result.mass = 0;
475
862
  }
476
863
  try {
477
864
  result.volume = massProps.Volume;
478
865
  }
479
- catch (e) {
866
+ catch (_e) {
480
867
  result.volume = 0;
481
868
  }
482
869
  try {
483
870
  result.surfaceArea = massProps.SurfaceArea;
484
871
  }
485
- catch (e) {
872
+ catch (_e) {
486
873
  result.surfaceArea = 0;
487
874
  }
488
875
  try {
@@ -498,13 +885,13 @@ export class SolidWorksAPI {
498
885
  result.centerOfMass = { x: 0, y: 0, z: 0 };
499
886
  }
500
887
  }
501
- catch (e) {
888
+ catch (_e) {
502
889
  result.centerOfMass = { x: 0, y: 0, z: 0 };
503
890
  }
504
891
  try {
505
892
  result.density = massProps.Density;
506
893
  }
507
- catch (e) {
894
+ catch (_e) {
508
895
  result.density = 0;
509
896
  }
510
897
  try {
@@ -519,11 +906,11 @@ export class SolidWorksAPI {
519
906
  Iyz: moi[5],
520
907
  Izx: moi[6],
521
908
  Izy: moi[7],
522
- Izz: moi[8]
909
+ Izz: moi[8],
523
910
  };
524
911
  }
525
912
  }
526
- catch (e) {
913
+ catch (_e) {
527
914
  // Moments of inertia might not be available
528
915
  }
529
916
  return result;
@@ -534,18 +921,57 @@ export class SolidWorksAPI {
534
921
  }
535
922
  // Helper to ensure current model is set
536
923
  ensureCurrentModel() {
537
- if (!this.currentModel && this.swApp) {
538
- // Try to get the active document
539
- try {
540
- this.currentModel = this.swApp.ActiveDoc;
924
+ if (!this.swApp)
925
+ return;
926
+ // Always try to sync with the active document
927
+ try {
928
+ const activeDoc = this.swApp.ActiveDoc;
929
+ if (activeDoc) {
930
+ // Check if the active doc has changed
931
+ if (!this.currentModel || this.currentModel !== activeDoc) {
932
+ this.currentModel = activeDoc;
933
+ }
541
934
  }
542
- catch (e) {
543
- // ActiveDoc might not be available
935
+ else if (!this.currentModel) {
936
+ // No active doc and no current model - try to get any open doc
937
+ try {
938
+ const docCount = this.swApp.GetDocumentCount();
939
+ if (docCount > 0) {
940
+ // Get the first document
941
+ const docs = this.swApp.GetDocuments();
942
+ if (docs && docs.length > 0) {
943
+ this.currentModel = docs[0];
944
+ }
945
+ }
946
+ }
947
+ catch (_e2) {
948
+ // GetDocumentCount might not be available
949
+ }
950
+ }
951
+ }
952
+ catch (_e) {
953
+ // ActiveDoc might throw if no documents are open
954
+ // Keep the current model if we have one
955
+ if (!this.currentModel) {
956
+ // Try alternative methods to get a document
957
+ try {
958
+ const frame = this.swApp.Frame();
959
+ if (frame) {
960
+ const modelWindow = frame.ModelWindow();
961
+ if (modelWindow) {
962
+ this.currentModel = modelWindow.ModelDoc;
963
+ }
964
+ }
965
+ }
966
+ catch (_e3) {
967
+ // Frame method might not work
968
+ }
544
969
  }
545
970
  }
546
971
  }
547
972
  // Helper to get current model
548
973
  getCurrentModel() {
974
+ this.ensureCurrentModel();
549
975
  return this.currentModel;
550
976
  }
551
977
  // Helper to get SolidWorks app