@typecad/cuttlefish 1.0.0-alpha.13 → 1.0.0-alpha.15

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 (343) hide show
  1. package/README.md +82 -79
  2. package/assets/editor-extensions/typecad-debug/README.md +141 -0
  3. package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
  4. package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
  5. package/assets/editor-extensions/typecad-debug/package.json +76 -0
  6. package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
  7. package/assets/editor-extensions/typecad-ui/README.md +52 -0
  8. package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
  9. package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
  10. package/assets/editor-extensions/typecad-ui/icon.png +0 -0
  11. package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
  12. package/assets/editor-extensions/typecad-ui/package.json +54 -0
  13. package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
  14. package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
  15. package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
  16. package/dist/api/config.d.ts +30 -27
  17. package/dist/api/schema/types.d.ts +20 -3
  18. package/dist/api/shared/async-runtime-static.d.ts +1 -1
  19. package/dist/api/shared/async-runtime-static.js +5 -5
  20. package/dist/api/shared/async-types.d.ts +3 -2
  21. package/dist/api/shared/board-catalog.d.ts +2 -0
  22. package/dist/api/shared/board-catalog.js +6 -0
  23. package/dist/api/shared/board-resolver.d.ts +4 -7
  24. package/dist/api/shared/board-resolver.js +2 -1
  25. package/dist/api/shared/coop-scheduler.d.ts +1 -1
  26. package/dist/api/shared/coop-scheduler.js +1 -1
  27. package/dist/api/shared/cpp-type-ir.d.ts +1 -1
  28. package/dist/api/shared/cpp-type-ir.js +1 -1
  29. package/dist/api/shared/display-profile.d.ts +1 -1
  30. package/dist/api/shared/display-profile.js +3 -5
  31. package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
  32. package/dist/api/shared/framework-manifest-registry.js +0 -1
  33. package/dist/api/shared/framework-manifest.d.ts +65 -507
  34. package/dist/api/shared/framework-manifest.js +6 -11
  35. package/dist/api/shared/hal-op-ir.d.ts +294 -685
  36. package/dist/api/shared/hal-op-ir.js +31 -65
  37. package/dist/api/shared/index.d.ts +0 -4
  38. package/dist/api/shared/index.js +1 -7
  39. package/dist/api/shared/ir-core.d.ts +6 -0
  40. package/dist/api/shared/ir-declarations.d.ts +4 -0
  41. package/dist/api/shared/ir.d.ts +1 -3
  42. package/dist/api/shared/platform-strategy.d.ts +14 -37
  43. package/dist/api/shared/polyfill-helper-registry.js +0 -5
  44. package/dist/api/shared/polyfill-types.js +0 -27
  45. package/dist/api/shared/promise-runtime.js +3 -3
  46. package/dist/api/shared/spdx-licenses.d.ts +12 -10
  47. package/dist/api/shared/spdx-licenses.js +1 -1
  48. package/dist/api/shared/toolchain-types.d.ts +1 -1
  49. package/dist/api/shared/toolchain-types.js +3 -3
  50. package/dist/api/shared/types.d.ts +0 -3
  51. package/dist/api/shared/validate-framework-manifest.js +13 -33
  52. package/dist/board-catalog/dts-reader.d.ts +220 -0
  53. package/dist/board-catalog/dts-reader.js +1052 -0
  54. package/dist/board-catalog/index.d.ts +11 -0
  55. package/dist/board-catalog/index.js +12 -0
  56. package/dist/board-catalog/pinconfig.d.ts +48 -0
  57. package/dist/board-catalog/pinconfig.js +263 -0
  58. package/dist/board-catalog/sdk.d.ts +82 -0
  59. package/dist/board-catalog/sdk.js +180 -0
  60. package/dist/board-catalog/store.d.ts +196 -0
  61. package/dist/board-catalog/store.js +363 -0
  62. package/dist/board-catalog/types.d.ts +233 -0
  63. package/dist/board-catalog/types.js +7 -0
  64. package/dist/board-catalog/walker.d.ts +112 -0
  65. package/dist/board-catalog/walker.js +1101 -0
  66. package/dist/cli-utils.d.ts +2 -2
  67. package/dist/cli-utils.js +5 -5
  68. package/dist/cli.js +227 -244
  69. package/dist/config-loader.d.ts +14 -19
  70. package/dist/config-loader.js +242 -78
  71. package/dist/config-schema.d.ts +19 -227
  72. package/dist/config-schema.js +9 -8
  73. package/dist/contract/board-generator.d.ts +4 -4
  74. package/dist/contract/board-generator.js +16 -5
  75. package/dist/contract/contract-parser.d.ts +36 -127
  76. package/dist/contract/contract-parser.js +76 -0
  77. package/dist/contract/index.d.ts +1 -1
  78. package/dist/contract/index.js +70 -21
  79. package/dist/create/active-board-catalog.d.ts +9 -0
  80. package/dist/create/active-board-catalog.js +94 -0
  81. package/dist/create/board-catalog.generated.d.ts +96 -0
  82. package/dist/create/board-catalog.generated.js +128737 -0
  83. package/dist/create/board-search.d.ts +23 -0
  84. package/dist/create/board-search.js +88 -0
  85. package/dist/create/editor-integration.d.ts +32 -0
  86. package/dist/create/editor-integration.js +257 -0
  87. package/dist/create/eslint-rules-template.d.ts +2 -2
  88. package/dist/create/framework-catalog.d.ts +48 -8
  89. package/dist/create/framework-catalog.js +58 -44
  90. package/dist/create/index.d.ts +8 -13
  91. package/dist/create/index.js +5 -9
  92. package/dist/create/mcu-target.d.ts +39 -0
  93. package/dist/create/mcu-target.js +80 -0
  94. package/dist/create/pack-targets.d.ts +19 -0
  95. package/dist/create/pack-targets.js +56 -0
  96. package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +8 -11
  97. package/dist/create/{init-scaffold.js → scaffold.js} +28 -87
  98. package/dist/create/templates.d.ts +51 -0
  99. package/dist/create/{init-templates.js → templates.js} +135 -116
  100. package/dist/create/wizard.d.ts +19 -0
  101. package/dist/create/wizard.js +314 -0
  102. package/dist/debug/preprocessor.d.ts +5 -0
  103. package/dist/debug/preprocessor.js +31 -7
  104. package/dist/diagnostics/diagnostics-report.d.ts +1 -1
  105. package/dist/diagnostics/diagnostics-report.js +3 -11
  106. package/dist/diagnostics/json-schema.d.ts +1 -1
  107. package/dist/diagnostics/md-writer.js +2 -2
  108. package/dist/diagnostics/mermaid-builder.d.ts +1 -1
  109. package/dist/diagnostics/mermaid-builder.js +1 -1
  110. package/dist/emit/cpp-emitter.js +4 -1
  111. package/dist/emit/emitters/class-emitter.js +32 -4
  112. package/dist/emit/emitters/emitter-context.d.ts +11 -0
  113. package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
  114. package/dist/emit/emitters/function-emitter-impl.js +33 -17
  115. package/dist/emit/emitters/output-finalizer.d.ts +7 -0
  116. package/dist/emit/emitters/output-finalizer.js +31 -23
  117. package/dist/emit/emitters/setup.js +147 -63
  118. package/dist/emit/emitters/top-level-prep.js +1 -1
  119. package/dist/emit/emitters/type-decl-emitter.js +13 -8
  120. package/dist/emit/emitters/ui-emitter.js +1 -1
  121. package/dist/emit/expression-renderer.d.ts +3 -3
  122. package/dist/emit/expression-renderer.js +17 -7
  123. package/dist/emit/route-hal-op.js +17 -48
  124. package/dist/emit/snprintf-helpers.d.ts +1 -3
  125. package/dist/emit/snprintf-helpers.js +1 -39
  126. package/dist/emit/statement-renderer.d.ts +0 -4
  127. package/dist/emit/statement-renderer.js +54 -45
  128. package/dist/emit/utils/async-state-machine.d.ts +16 -9
  129. package/dist/emit/utils/async-state-machine.js +56 -54
  130. package/dist/emit/utils/comment-helpers.d.ts +0 -8
  131. package/dist/emit/utils/comment-helpers.js +1 -1
  132. package/dist/emit/utils/cpp-helpers.d.ts +2 -2
  133. package/dist/emit/utils/cpp-helpers.js +2 -2
  134. package/dist/emit/utils/hal-op-cpp-type.js +4 -6
  135. package/dist/emit/utils/index.d.ts +3 -3
  136. package/dist/emit/utils/index.js +3 -3
  137. package/dist/emit/utils/type-inference.d.ts +1 -29
  138. package/dist/emit/utils/type-inference.js +0 -75
  139. package/dist/framework-package.d.ts +3 -0
  140. package/dist/framework-package.js +23 -6
  141. package/dist/framework-registry.d.ts +5 -5
  142. package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
  143. package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
  144. package/dist/frameworks/native/index.d.ts +3 -0
  145. package/dist/frameworks/native/index.js +15 -0
  146. package/dist/frameworks/native/native-compile.d.ts +17 -0
  147. package/dist/frameworks/native/native-compile.js +170 -0
  148. package/dist/frameworks/native/native-config.d.ts +41 -0
  149. package/dist/frameworks/native/native-config.js +7 -0
  150. package/dist/frameworks/native/strategy.d.ts +97 -0
  151. package/dist/frameworks/native/strategy.js +664 -0
  152. package/dist/ir/board-resolver.d.ts +18 -23
  153. package/dist/ir/board-resolver.js +43 -401
  154. package/dist/ir/build-ir-state.d.ts +3 -0
  155. package/dist/ir/build-ir-state.js +42 -0
  156. package/dist/ir/build-ir.d.ts +1 -1
  157. package/dist/ir/build-ir.js +64 -45
  158. package/dist/ir/declaration-builders.js +1 -0
  159. package/dist/ir/expression-to-ir.js +17 -10
  160. package/dist/ir/hal/hal-emitter.d.ts +0 -2
  161. package/dist/ir/hal/hal-emitter.js +92 -41
  162. package/dist/ir/hal/hal-parser.d.ts +5 -5
  163. package/dist/ir/hal/hal-parser.js +128 -36
  164. package/dist/ir/hal/hal-plugins.d.ts +0 -1
  165. package/dist/ir/hal/hal-plugins.js +425 -716
  166. package/dist/ir/heap-analysis.js +2 -41
  167. package/dist/ir/identifier-collector.js +32 -20
  168. package/dist/ir/network-validation.js +7 -11
  169. package/dist/ir/ownership-analysis.js +75 -13
  170. package/dist/ir/peripheral-usage.d.ts +8 -2
  171. package/dist/ir/peripheral-usage.js +78 -149
  172. package/dist/ir/peripheral-validation.js +23 -3
  173. package/dist/ir/pin-capability-validation.d.ts +12 -0
  174. package/dist/ir/pin-capability-validation.js +61 -97
  175. package/dist/ir/pin-mode-validation.js +5 -5
  176. package/dist/ir/program-analysis.d.ts +8 -15
  177. package/dist/ir/program-analysis.js +140 -323
  178. package/dist/ir/pulldown-validation.js +11 -4
  179. package/dist/ir/resource-analysis.js +15 -3
  180. package/dist/ir/statement-to-ir.js +0 -6
  181. package/dist/ir/timing-validation.js +1 -1
  182. package/dist/ir/transformers/array-methods.js +11 -5
  183. package/dist/ir/transformers/call-statement.js +20 -87
  184. package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
  185. package/dist/ir/transformers/callback-context-registry.js +8 -16
  186. package/dist/ir/transformers/control-flow.js +0 -13
  187. package/dist/ir/transformers/expressions.js +10 -9
  188. package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
  189. package/dist/ir/transformers/hal-call-resolver.js +24 -10
  190. package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
  191. package/dist/ir/transformers/hal-emit-helpers.js +2 -2
  192. package/dist/ir/transformers/namespace-methods.js +1 -1
  193. package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
  194. package/dist/ir/transformers/ui-callback-lowering.js +0 -24
  195. package/dist/ir/transformers/variables.js +338 -42
  196. package/dist/ir/try-catch-validation.js +4 -3
  197. package/dist/ir/type-resolution.js +15 -4
  198. package/dist/ir/validation-orchestrator.js +0 -9
  199. package/dist/libdef/cpp-to-decl.d.ts +0 -9
  200. package/dist/libdef/cpp-to-decl.js +0 -72
  201. package/dist/libdef/registry.d.ts +0 -1
  202. package/dist/libdef/registry.js +1 -24
  203. package/dist/library/catalog.d.ts +35 -0
  204. package/dist/library/catalog.js +67 -0
  205. package/dist/library/cli.d.ts +2 -0
  206. package/dist/library/cli.js +168 -0
  207. package/dist/library/init.d.ts +25 -0
  208. package/dist/library/init.js +397 -0
  209. package/dist/library/install.d.ts +9 -0
  210. package/dist/library/install.js +80 -0
  211. package/dist/library/registry-search.d.ts +34 -0
  212. package/dist/library/registry-search.js +50 -0
  213. package/dist/library/validate.d.ts +17 -0
  214. package/dist/library/validate.js +175 -0
  215. package/dist/library-packages.d.ts +95 -0
  216. package/dist/library-packages.js +275 -0
  217. package/dist/mapping/peripheral-names.js +9 -4
  218. package/dist/mapping/source-map.d.ts +3 -4
  219. package/dist/mapping/source-map.js +12 -18
  220. package/dist/orchestrator/graph-builder.d.ts +3 -3
  221. package/dist/orchestrator/graph-builder.js +29 -12
  222. package/dist/orchestrator/type-checker.d.ts +3 -3
  223. package/dist/orchestrator/type-checker.js +3 -3
  224. package/dist/platform/async-runtime.js +1 -1
  225. package/dist/platform/coop-scheduler-runtime.js +2 -2
  226. package/dist/platform/generic-debug-codegen.d.ts +36 -0
  227. package/dist/platform/generic-debug-codegen.js +185 -0
  228. package/dist/platform/generic-strategy.d.ts +3 -4
  229. package/dist/platform/generic-strategy.js +5 -80
  230. package/dist/platform/index.js +1 -1
  231. package/dist/platform/registry.d.ts +2 -2
  232. package/dist/platform/registry.js +2 -2
  233. package/dist/preview/client.js +17 -3
  234. package/dist/safety/asil-decorators.d.ts +32 -0
  235. package/dist/safety/asil-decorators.js +32 -0
  236. package/dist/safety/authoring.d.ts +85 -0
  237. package/dist/safety/authoring.js +61 -0
  238. package/dist/safety/engine.d.ts +3 -0
  239. package/dist/safety/engine.js +83 -0
  240. package/dist/safety/hal/ops.d.ts +48 -0
  241. package/dist/safety/hal/ops.js +46 -0
  242. package/dist/safety/iso26262/analyze.d.ts +13 -0
  243. package/dist/safety/iso26262/analyze.js +29 -0
  244. package/dist/safety/iso26262/asil.d.ts +10 -0
  245. package/dist/safety/iso26262/asil.js +22 -0
  246. package/dist/safety/iso26262/collect.d.ts +14 -0
  247. package/dist/safety/iso26262/collect.js +137 -0
  248. package/dist/safety/iso26262/goto-checker.d.ts +10 -0
  249. package/dist/safety/iso26262/goto-checker.js +72 -0
  250. package/dist/safety/iso26262/heap-checker.d.ts +7 -0
  251. package/dist/safety/iso26262/heap-checker.js +57 -0
  252. package/dist/safety/iso26262/init-checker.d.ts +13 -0
  253. package/dist/safety/iso26262/init-checker.js +127 -0
  254. package/dist/safety/iso26262/loop-checker.d.ts +7 -0
  255. package/dist/safety/iso26262/loop-checker.js +86 -0
  256. package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
  257. package/dist/safety/iso26262/recursion-checker.js +134 -0
  258. package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
  259. package/dist/safety/iso26262/sidecar-writer.js +13 -0
  260. package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
  261. package/dist/safety/passes/pinMode-intercept.js +60 -0
  262. package/dist/safety/runtime/mode-table.d.ts +5 -0
  263. package/dist/safety/runtime/mode-table.js +55 -0
  264. package/dist/safety/runtime/polyfills.d.ts +6 -0
  265. package/dist/safety/runtime/polyfills.js +12 -0
  266. package/dist/safety/runtime/result-struct.d.ts +11 -0
  267. package/dist/safety/runtime/result-struct.js +98 -0
  268. package/dist/safety/runtime/safe-int.d.ts +33 -0
  269. package/dist/safety/runtime/safe-int.js +170 -0
  270. package/dist/safety/runtime/safe-traits.d.ts +4 -0
  271. package/dist/safety/runtime/safe-traits.js +95 -0
  272. package/dist/safety/runtime/safe-variable.d.ts +39 -0
  273. package/dist/safety/runtime/safe-variable.js +226 -0
  274. package/dist/safety/runtime/vote.d.ts +8 -0
  275. package/dist/safety/runtime/vote.js +92 -0
  276. package/dist/safety/runtime/write-verify.d.ts +8 -0
  277. package/dist/safety/runtime/write-verify.js +71 -0
  278. package/dist/safety/safe-int-types.d.ts +45 -0
  279. package/dist/safety/safe-int-types.js +25 -0
  280. package/dist/safety/safe-variable-types.d.ts +29 -0
  281. package/dist/safety/safe-variable-types.js +19 -0
  282. package/dist/safety/safety-bridge.d.ts +5 -6
  283. package/dist/safety/safety-bridge.js +15 -28
  284. package/dist/safety/sidecar-bridge.d.ts +1 -3
  285. package/dist/safety/sidecar-bridge.js +3 -20
  286. package/dist/safety/specifiers.d.ts +6 -0
  287. package/dist/safety/specifiers.js +14 -0
  288. package/dist/safety-hook.d.ts +8 -7
  289. package/dist/safety-hook.js +12 -13
  290. package/dist/testing.d.ts +5 -6
  291. package/dist/testing.js +5 -5
  292. package/dist/transpile/resolution.d.ts +1 -1
  293. package/dist/transpile/resolution.js +18 -9
  294. package/dist/transpile/test-pins.d.ts +18 -0
  295. package/dist/transpile/test-pins.js +142 -0
  296. package/dist/transpile.d.ts +1 -2
  297. package/dist/transpile.js +90 -29
  298. package/dist/types.d.ts +45 -26
  299. package/dist/ui-hook.d.ts +1 -1
  300. package/dist/utils/cli.d.ts +2 -2
  301. package/dist/utils/cli.js +160 -157
  302. package/dist/utils/fs.d.ts +3 -4
  303. package/dist/utils/fs.js +4 -5
  304. package/dist/utils/strings.d.ts +0 -1
  305. package/dist/utils/strings.js +0 -8
  306. package/dist/utils/ui.d.ts +5 -2
  307. package/dist/utils/ui.js +13 -3
  308. package/package.json +158 -149
  309. package/dist/add-preset.d.ts +0 -4
  310. package/dist/add-preset.js +0 -74
  311. package/dist/api/shared/async-symbol-detector.d.ts +0 -11
  312. package/dist/api/shared/async-symbol-detector.js +0 -140
  313. package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
  314. package/dist/api/shared/native-display-op-resolver.js +0 -64
  315. package/dist/create/board-checklist.d.ts +0 -2
  316. package/dist/create/board-checklist.js +0 -52
  317. package/dist/create/board-codegen.d.ts +0 -9
  318. package/dist/create/board-codegen.js +0 -238
  319. package/dist/create/board-generators.d.ts +0 -12
  320. package/dist/create/board-generators.js +0 -651
  321. package/dist/create/board-spec.d.ts +0 -637
  322. package/dist/create/board-spec.js +0 -214
  323. package/dist/create/init-templates.d.ts +0 -28
  324. package/dist/create/init-wizard.d.ts +0 -8
  325. package/dist/create/init-wizard.js +0 -182
  326. package/dist/install/framework-catalog.d.ts +0 -53
  327. package/dist/install/framework-catalog.js +0 -107
  328. package/dist/install/handle-install.d.ts +0 -35
  329. package/dist/install/handle-install.js +0 -177
  330. package/dist/install/index.d.ts +0 -4
  331. package/dist/install/index.js +0 -3
  332. package/dist/ir/pin-state-tracking.d.ts +0 -58
  333. package/dist/ir/pin-state-tracking.js +0 -182
  334. package/dist/ir/pwm-timer-sharing.d.ts +0 -4
  335. package/dist/ir/pwm-timer-sharing.js +0 -94
  336. package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
  337. package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
  338. package/dist/libdef/component-decls.d.ts +0 -2
  339. package/dist/libdef/component-decls.js +0 -6
  340. package/dist/libdef/component-discovery.d.ts +0 -43
  341. package/dist/libdef/component-discovery.js +0 -83
  342. package/dist/theme-tokens.d.ts +0 -22
  343. package/dist/theme-tokens.js +0 -172
package/README.md CHANGED
@@ -1,79 +1,82 @@
1
- # `@typecad/cuttlefish`
2
-
3
- TypeScript → C++ transpiler for embedded firmware. Targets native (desktop),
4
- Arduino, and bare-metal MCU builds from a single TypeScript codebase.
5
-
6
- `cuttlefish` is the command-line tool at the center of the [TypeCAD](https://cuttlefish.typecad.net)
7
- toolchain: it loads `cuttlefish.config.ts`, transpiles TypeScript firmware to
8
- C++, and can chain compile, upload, and serial-monitor steps.
9
-
10
- ## Quick start
11
-
12
- From a project root containing `cuttlefish.config.ts`:
13
-
14
- ```bash
15
- npx @typecad/cuttlefish build
16
- npx @typecad/cuttlefish build --compile --upload --port COM4
17
- npx @typecad/cuttlefish build --compile --upload --monitor --port COM4 --baud 115200
18
- ```
19
-
20
- Scaffold a starter project with the built-in wizard:
21
-
22
- ```bash
23
- npx @typecad/cuttlefish create --board arduino:avr:uno --framework arduino
24
- ```
25
-
26
- ## Commands
27
-
28
- | Command | Description |
29
- | --- | --- |
30
- | `cuttlefish build` | Transpile the entry file (default). Accepts `--compile`, `--upload`, `--monitor`, `--port`, `--baud`. |
31
- | `cuttlefish create` | Generate a starter project and `cuttlefish.config.ts`. |
32
- | `cuttlefish board-add` | Add a new board package via the board-codegen scaffolder. |
33
- | `cuttlefish preview` | Launch the browser preview server for a UI project. |
34
- | `cuttlefish map-error <mapFile>` | Map a C++ compiler error back to its TypeScript source location. |
35
- | `cuttlefish gen-decls` | Generate type declaration stubs. |
36
- | `cuttlefish gen-libdefs <input.ts>` | Generate library definition stubs for third-party imports. |
37
-
38
- ### Flags (for `build`)
39
-
40
- - `--compile` — transpile, then compile via the active framework's toolchain (`arduino-cli` for Arduino, `g++` for native).
41
- - `--upload` — flash firmware to the board (implies `--compile`).
42
- - `--monitor` — open a serial monitor after upload.
43
- - `--port <port>` serial port for upload/monitor (e.g. `COM4`, `/dev/ttyUSB0`).
44
- - `--baud <rate>` — serial monitor baud rate.
45
-
46
- ## Configuration
47
-
48
- The CLI reads `cuttlefish.config.ts` from the current working directory and
49
- treats it as the source of truth. When no config file is present, command-line
50
- flags such as `--fqbn` and `--board` supply board and build settings.
51
-
52
- ```ts
53
- import type { CuttlefishConfig } from '@typecad/cuttlefish/api';
54
-
55
- const config: CuttlefishConfig = {
56
- entry: './src/main.ts',
57
- target: 'esp32',
58
- mcu: '@typecad/mcu-esp32',
59
- board: '@typecad/board-esp32-devkit',
60
- framework: '@typecad/framework-arduino',
61
- };
62
-
63
- export default config;
64
- ```
65
-
66
- ## Ecosystem
67
-
68
- `@typecad/cuttlefish` is the transpiler core. It pairs with sibling packages:
69
-
70
- - [`@typecad/hal`](https://cuttlefish.typecad.net) — hardware abstraction (GPIO, I2C, SPI, UART) as regular TypeScript.
71
- - [`@typecad/ui`](https://cuttlefish.typecad.net) — HTML/CSS-driven graphics for microcontroller displays.
72
- - [`@typecad/expect`](https://cuttlefish.typecad.net) — hardware test framework (vitest-style assertions over serial).
73
- - [`@typecad/framework-arduino`](https://cuttlefish.typecad.net) — Arduino framework code-gen strategy.
74
- - [`@typecad/framework-native`](https://cuttlefish.typecad.net) — native desktop C++ code-gen strategy.
75
- - `@typecad/mcu-*` and `@typecad/board-*` silicon- and board-level pin/peripheral definitions.
76
-
77
- ## License
78
-
79
- MIT
1
+ # `@typecad/cuttlefish`
2
+
3
+ TypeScript → C++ transpiler for embedded firmware. Targets native (desktop)
4
+ and Zephyr-supported embedded boards from a single TypeScript codebase.
5
+
6
+ `cuttlefish` is the command-line tool at the center of the [TypeCAD](https://cuttlefish.typecad.net)
7
+ toolchain: it loads `cuttlefish.config.ts`, transpiles TypeScript firmware to
8
+ C++, and can chain compile, upload, and serial-monitor steps.
9
+
10
+ ## Quick start
11
+
12
+ From a project root containing `cuttlefish.config.ts`:
13
+
14
+ ```bash
15
+ npx @typecad/cuttlefish build
16
+ npx @typecad/cuttlefish build --compile --upload --port COM4
17
+ npx @typecad/cuttlefish build --compile --upload --monitor --port COM4 --baud 115200
18
+ ```
19
+
20
+ Scaffold a starter project with the built-in wizard:
21
+
22
+ ```bash
23
+ npx @typecad/cuttlefish create --board esp32s3
24
+ ```
25
+
26
+ ## Commands
27
+
28
+ | Command | Description |
29
+ | --- | --- |
30
+ | `cuttlefish build` | Transpile the entry file (default). Accepts `--compile`, `--upload`, `--monitor`, `--port`, `--baud`. |
31
+ | `cuttlefish create` | Generate a starter project and `cuttlefish.config.ts`. |
32
+ | `cuttlefish preview` | Launch the browser preview server for a UI project. |
33
+ | `cuttlefish gen-decls <file.h\|file.cpp\|--all <dir>>` | Generate `.d.ts` declaration stubs from C++ headers. |
34
+ | `cuttlefish doctor` | Check the active framework's environment (e.g. toolchain + board support). |
35
+ | `cuttlefish licenses [--all] [--strict]` | Scan this project's libraries for SPDX licenses. |
36
+ | `cuttlefish board sync [zephyr-base]` | Rebuild the local board catalog from your Zephyr tree's board DTS files. The catalog is machine-local there is no compiled-in board database; builds create and refresh it automatically, this command forces a rebuild. |
37
+ | `cuttlefish board regen` | Regenerate the project-local board module (`.cuttlefish/board.ts` + `board.json`). Builds also regenerate it automatically whenever any input changes (config board, catalog, or Zephyr tree). |
38
+ | `cuttlefish library <search\|install\|init\|validate>` | The cuttlefish library package manager (npm keywords are the catalog). |
39
+
40
+ ### Flags (for `build`)
41
+
42
+ - `--compile` — transpile, then compile via the active framework's toolchain (`west` for Zephyr, `g++` for native).
43
+ - `--upload`flash firmware to the board (requires `--compile`).
44
+ - `--monitor`open a serial monitor after upload.
45
+ - `--port <port>` — serial port for upload/monitor (e.g. `COM4`, `/dev/ttyUSB0`).
46
+ - `--baud <rate>` — serial monitor baud rate.
47
+
48
+ ## Configuration
49
+
50
+ The CLI reads `cuttlefish.config.ts` from the current working directory and
51
+ treats it as the source of truth. When no config file is present, command-line
52
+ flags such as `--board` and `--build-target` supply board and build settings.
53
+
54
+ ```ts
55
+ import type { CuttlefishConfig } from '@typecad/cuttlefish/api';
56
+
57
+ const config: CuttlefishConfig = {
58
+ entry: './src/main.ts',
59
+ board: 'xiao_ble/nrf52840',
60
+ framework: '@typecad/framework-zephyr',
61
+ };
62
+
63
+ export default config;
64
+ ```
65
+
66
+ ## Ecosystem
67
+
68
+ `@typecad/cuttlefish` is the transpiler core. It pairs with sibling packages:
69
+
70
+ - [`@typecad/hal`](https://cuttlefish.typecad.net) — hardware abstraction (GPIO, I2C, SPI, UART) as regular TypeScript.
71
+ - [`@typecad/ui`](https://cuttlefish.typecad.net) — HTML/CSS-driven graphics for microcontroller displays.
72
+ - [`@typecad/expect`](https://cuttlefish.typecad.net) — hardware test framework (vitest-style assertions over serial).
73
+ - [`@typecad/framework-zephyr`](https://cuttlefish.typecad.net) — Zephyr RTOS framework (build, flashing, and the bundled Zephyr toolchain installer).
74
+
75
+ Built in, no separate package: the **native** desktop target (`framework:
76
+ '@typecad/framework-native'` resolves inside cuttlefish) and the **safety**
77
+ engine (verified GPIO reads, ISO 26262 analysis — author via
78
+ `@typecad/cuttlefish/safety`).
79
+
80
+ ## License
81
+
82
+ MIT
@@ -0,0 +1,141 @@
1
+ # TypeCAD Debug
2
+
3
+ A Visual Studio Code extension that bridges VSCode's breakpoint gutter to the
4
+ TypeCAD `Serial.print` debug pipeline. Set breakpoints in your `.ts` source;
5
+ this extension syncs them to `.cuttlefish/breakpoints.json`, which the
6
+ `@typecad/cuttlefish` transpiler reads (when run with `--debug`) to inject
7
+ `Serial.println` instrumentation that reports variable values and lets you
8
+ step through execution.
9
+
10
+ This is the producer half of a two-part system. The consumer half lives in
11
+ [`@typecad/cuttlefish`](../../packages/cuttlefish/src/debug/) and is the
12
+ authoritative source for the on-disk schema and matching behavior described
13
+ below.
14
+
15
+ ## Install
16
+
17
+ This package is `private: true` and is **not** published to the npm registry
18
+ or the VS Code Marketplace. Build the VSIX locally:
19
+
20
+ ```sh
21
+ cd packages/vscode-typecad-debug
22
+ npm install
23
+ npm run compile
24
+ npm run package # produces vscode-typecad-debug-0.2.0.vsix
25
+ code --install-extension vscode-typecad-debug-0.2.0.vsix
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ 1. Open the Command Palette (`Ctrl/Cmd+Shift+P`).
31
+ 2. Run **TypeCAD: Debug with Breakpoints** — or set red-dot breakpoints in the
32
+ gutter and run `cuttlefish build --debug` in a terminal.
33
+ 3. Breakpoints (including conditional breakpoints and logpoints) are written
34
+ to `.cuttlefish/breakpoints.json` on every breakpoint change and on every
35
+ `.ts` save.
36
+ 4. Upload the instrumented firmware and open a serial monitor (`--monitor`).
37
+ At each breakpoint the firmware prints the location, the original source
38
+ line, and the variables in scope, then halts. Two keys are available:
39
+ - **ENTER** — continue (the breakpoint will halt here again the next time
40
+ execution reaches it).
41
+ - **`s`** — skip this breakpoint for the rest of the run: it won't halt
42
+ here again until the device reboots. Other breakpoints are unaffected.
43
+
44
+ ### Commands
45
+
46
+ | Command | Title |
47
+ |---|---|
48
+ | `typecad-debug.toggleBreakpoint` | TypeCAD: Toggle Breakpoint (bound to `F9` in `.ts` files) |
49
+ | `typecad-debug.clearAllBreakpoints` | TypeCAD: Clear All Breakpoints |
50
+ | `typecad-debug.debugWithBreakpoints` | TypeCAD: Debug with Breakpoints |
51
+ | `typecad-debug.syncBreakpoints` | TypeCAD: Sync Breakpoints from VS Code |
52
+ | `typecad-debug.generateDeclaration` | TypeCAD: Generate Declaration from C++ |
53
+
54
+ ### Enabling instrumentation
55
+
56
+ Breakpoints are only injected when cuttlefish is run with `--debug`:
57
+
58
+ ```sh
59
+ cuttlefish build --debug # uses cuttlefish.config.ts entry
60
+ cuttlefish src/index.ts --debug --compile --upload --port COM4
61
+ ```
62
+
63
+ See `cuttlefish --help` for the full `--debug` description.
64
+
65
+ ## `.cuttlefish/breakpoints.json` schema
66
+
67
+ The file lives at the project root (or any ancestor of the entry file's
68
+ directory). Each entry uses **the basename** of the source file as `file`
69
+ (this is the only path form that matches reliably on both Windows and POSIX
70
+ under cuttlefish's basename-matching loader):
71
+
72
+ ```jsonc
73
+ {
74
+ "breakpoints": [
75
+ { "file": "index.ts", "line": 12 },
76
+ { "file": "index.ts", "line": 27, "condition": "counter > 5" },
77
+ { "file": "sensor.ts", "line": 8, "logMessage": "reading = {value}" }
78
+ ]
79
+ }
80
+ ```
81
+
82
+ | Field | Type | Required | Notes |
83
+ |---|---|---|---|
84
+ | `file` | string | yes | Source file **basename** (e.g. `index.ts`). |
85
+ | `line` | number | yes | 1-indexed line number. `0` is dropped. |
86
+ | `condition` | string | no | Conditional expression; `===`/`!==` are auto-normalized to `==`/`!=` for C++. |
87
+ | `logMessage` | string | no | Logpoint with `{variable}` interpolation. When present, the breakpoint logs instead of halting. |
88
+
89
+ Two source files sharing the same basename in one project will share
90
+ breakpoints — acceptable for typical single-program projects.
91
+
92
+ ## Native debugging on ESP32-S3
93
+
94
+ For ESP32-S3, this extension's printf instrumentation is superseded by a
95
+ native GDB path. `cuttlefish build --debug` on `esp32s3` emits `#line`
96
+ directives in the generated C++ and writes `.vscode/launch.json` +
97
+ `tasks.json` (at the cuttlefish project root, where VS Code reads them) plus
98
+ `.cuttlefish/openocd.cfg` next to the build output. Press **F5** in VS Code
99
+ and the generated config attaches GDB to the chip's built-in USB-Serial-JTAG
100
+ — one USB cable, no external probe.
101
+
102
+ For Zephyr projects (`@typecad/framework-zephyr` on an esp32s3 board),
103
+ `cuttlefish create` writes the same starter artifacts at project creation —
104
+ `.vscode/launch.json` + `tasks.json` + `src/out/.cuttlefish/openocd.cfg` —
105
+ so F5 works on a fresh project before any build: the preLaunch task runs
106
+ `cuttlefish build --compile --upload --debug`, which builds, flashes, and
107
+ re-merges the launch entry with the build-cache-resolved gdbPath. (The
108
+ starter gdbPath is probed from `$ZEPHYR_SDK_INSTALL_DIR`, the
109
+ zephyr-installer micromamba layout, or `~/zephyr-sdk-*`.)
110
+
111
+ `launch.json` ships a single **`cortex-debug`** configuration (`servertype:
112
+ "openocd"`, or `"jlink"` when the board's probe method is a JLink runner).
113
+ The cortex-debug extension starts OpenOCD itself as a child process, passing
114
+ the generated `.cuttlefish/openocd.cfg`; the `preLaunchTask` is just
115
+ `build + flash` — no competing OpenOCD process. Install the cortex-debug
116
+ extension (ESP32 targets also need OpenOCD — the framework probes the
117
+ openocd-esp32 install layout or the Zephyr SDK's own openocd), and set the
118
+ serial port through the `CUTTLEFISH_PORT` env var or pass
119
+ `--port`.
120
+
121
+ The printf instrumentation documented below remains the path for targets
122
+ that don't ship a native GDB path yet.
123
+
124
+ ## Limitations
125
+
126
+ - This is a printf-based instrumentation shim, not a DAP debug
127
+ adapter. There is no native step/step-in/step-out — each breakpoint halts
128
+ until ENTER (continue) or `s` (skip this breakpoint for the run) is received
129
+ over serial. **On ESP32-S3, use the native GDB path above instead** — it
130
+ provides full stepping, call stacks, and TS-named variable inspection.
131
+ - The scope analyzer captures module-scope identifiers plus locals and
132
+ parameters in the enclosing function. Member access and arbitrary
133
+ expressions are not resolved; `{ value }` in a logpoint emits the literal
134
+ `"{value}"` if `value` is not in scope.
135
+ - Baud rate is fixed by the framework's console shim regardless of the CLI
136
+ `--baud` value.
137
+ - **Target-specific output:** under @typecad/framework-zephyr the injected
138
+ code routes through the board console (`printk`/shell backend) and blocks on
139
+ a getchar-equivalent with the idle thread feeding — so a debug build must
140
+ have a serial monitor attached (e.g. `cuttlefish build --monitor`), or it
141
+ will hang at the first breakpoint until power is cycled.
@@ -0,0 +1,347 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // vscode-typecad-debug — VSCode Extension
4
+ //
5
+ // Tracks breakpoints in TypeScript files and syncs them to
6
+ // .cuttlefish/breakpoints.json for the TypeCAD debug preprocessor.
7
+ // Also auto-generates .d.ts declaration files from C++ sources.
8
+ //
9
+ // The breakpoint file is read by @typecad/cuttlefish when invoked with
10
+ // `--debug`. The preprocessor injects Serial.println instrumentation at the
11
+ // recorded line numbers; run `cuttlefish build --debug` (or `cuttlefish
12
+ // index.ts --debug`) to enable it.
13
+ //
14
+ // IMPORTANT: the `file` field in each breakpoint entry is written as the
15
+ // basename only (e.g. "index.ts"). The cuttlefish loader matches breakpoints
16
+ // by exact → basename → suffix, and basename matching is the only strategy
17
+ // that works identically on Windows (backslash) and POSIX (forward slash)
18
+ // without slash normalization. The trade-off is that two files with the same
19
+ // basename in one project share breakpoints — acceptable for typical
20
+ // single-sketch Arduino projects.
21
+ // ---------------------------------------------------------------------------
22
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ var desc = Object.getOwnPropertyDescriptor(m, k);
25
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
26
+ desc = { enumerable: true, get: function() { return m[k]; } };
27
+ }
28
+ Object.defineProperty(o, k2, desc);
29
+ }) : (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ o[k2] = m[k];
32
+ }));
33
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
34
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
35
+ }) : function(o, v) {
36
+ o["default"] = v;
37
+ });
38
+ var __importStar = (this && this.__importStar) || (function () {
39
+ var ownKeys = function(o) {
40
+ ownKeys = Object.getOwnPropertyNames || function (o) {
41
+ var ar = [];
42
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
43
+ return ar;
44
+ };
45
+ return ownKeys(o);
46
+ };
47
+ return function (mod) {
48
+ if (mod && mod.__esModule) return mod;
49
+ var result = {};
50
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
51
+ __setModuleDefault(result, mod);
52
+ return result;
53
+ };
54
+ })();
55
+ Object.defineProperty(exports, "__esModule", { value: true });
56
+ exports.activate = activate;
57
+ exports.deactivate = deactivate;
58
+ const vscode = __importStar(require("vscode"));
59
+ const fs = __importStar(require("node:fs"));
60
+ const path = __importStar(require("node:path"));
61
+ const node_child_process_1 = require("node:child_process");
62
+ // ---------------------------------------------------------------------------
63
+ // Constants
64
+ // ---------------------------------------------------------------------------
65
+ /** Relative to the workspace root. */
66
+ const BREAKPOINTS_DIR = '.cuttlefish';
67
+ const BREAKPOINTS_FILE = 'breakpoints.json';
68
+ // ---------------------------------------------------------------------------
69
+ // Extension Activation
70
+ // ---------------------------------------------------------------------------
71
+ function activate(context) {
72
+ console.log('TypeCAD Debug extension activated');
73
+ const breakpointTracker = new BreakpointTracker();
74
+ const toggleCmd = vscode.commands.registerCommand('typecad-debug.toggleBreakpoint', () => breakpointTracker.toggleBreakpoint());
75
+ const clearAllCmd = vscode.commands.registerCommand('typecad-debug.clearAllBreakpoints', () => breakpointTracker.clearAllBreakpoints());
76
+ const debugCmd = vscode.commands.registerCommand('typecad-debug.debugWithBreakpoints', () => breakpointTracker.debugWithBreakpoints());
77
+ const syncCmd = vscode.commands.registerCommand('typecad-debug.syncBreakpoints', () => breakpointTracker.syncFromVSCode());
78
+ // Auto-sync breakpoints when saving TypeScript files.
79
+ const saveListener = vscode.workspace.onDidSaveTextDocument((doc) => {
80
+ if (doc.fileName.endsWith('.ts') && !doc.fileName.includes('node_modules')) {
81
+ breakpointTracker.syncFromVSCode();
82
+ }
83
+ });
84
+ const declGenerator = new DeclarationGenerator();
85
+ const genDeclCmd = vscode.commands.registerCommand('typecad-debug.generateDeclaration', () => declGenerator.generateForCurrentFile());
86
+ // Auto-generate a .d.ts when a C++ file is saved and the sidecar is missing.
87
+ const cppSaveListener = vscode.workspace.onDidSaveTextDocument((doc) => {
88
+ if (doc.fileName.endsWith('.cpp') && !doc.fileName.includes('node_modules')) {
89
+ declGenerator.checkAndGenerate(doc.fileName);
90
+ }
91
+ });
92
+ context.subscriptions.push(toggleCmd, clearAllCmd, debugCmd, syncCmd, saveListener, breakpointTracker, genDeclCmd, cppSaveListener, declGenerator);
93
+ }
94
+ function deactivate() { }
95
+ // ---------------------------------------------------------------------------
96
+ // Breakpoint Tracker
97
+ // ---------------------------------------------------------------------------
98
+ class BreakpointTracker {
99
+ constructor() {
100
+ /** file fsPath → line → Breakpoint. Keys are full fsPaths for dedup. */
101
+ this.breakpoints = new Map();
102
+ this._onDidChange = new vscode.EventEmitter();
103
+ this.onDidChange = this._onDidChange.event;
104
+ this.loadFromFile();
105
+ // VSCode breakpoint gutter changes (red dots, conditions, logpoints).
106
+ vscode.debug.onDidChangeBreakpoints(() => {
107
+ console.log('TypeCAD: Breakpoint change detected');
108
+ this.syncFromVSCode();
109
+ });
110
+ // Re-sync when switching editor so a stale in-memory map doesn't survive.
111
+ vscode.window.onDidChangeActiveTextEditor((editor) => {
112
+ if (editor) {
113
+ this.syncFromVSCode();
114
+ }
115
+ });
116
+ }
117
+ /**
118
+ * Toggle a breakpoint at the current cursor position.
119
+ */
120
+ toggleBreakpoint() {
121
+ const editor = vscode.window.activeTextEditor;
122
+ if (!editor)
123
+ return;
124
+ const filePath = editor.document.uri.fsPath;
125
+ const fileName = path.basename(filePath);
126
+ const line = editor.selection.active.line + 1; // 1-indexed
127
+ if (!this.breakpoints.has(fileName)) {
128
+ this.breakpoints.set(fileName, new Map());
129
+ }
130
+ const fileBreakpoints = this.breakpoints.get(fileName);
131
+ if (fileBreakpoints.has(line)) {
132
+ fileBreakpoints.delete(line);
133
+ vscode.window.showInformationMessage(`TypeCAD: Breakpoint removed at line ${line}`);
134
+ }
135
+ else {
136
+ fileBreakpoints.set(line, { file: fileName, line });
137
+ vscode.window.showInformationMessage(`TypeCAD: Breakpoint added at line ${line}`);
138
+ }
139
+ this.saveToFile();
140
+ this._onDidChange.fire();
141
+ }
142
+ /**
143
+ * Clear all breakpoints.
144
+ */
145
+ clearAllBreakpoints() {
146
+ this.breakpoints.clear();
147
+ this.saveToFile();
148
+ vscode.window.showInformationMessage('TypeCAD: All breakpoints cleared');
149
+ this._onDidChange.fire();
150
+ }
151
+ /**
152
+ * Save breakpoints, then run `cuttlefish build --debug` in a terminal.
153
+ */
154
+ async debugWithBreakpoints() {
155
+ const editor = vscode.window.activeTextEditor;
156
+ if (!editor) {
157
+ vscode.window.showErrorMessage('TypeCAD: No active editor');
158
+ return;
159
+ }
160
+ this.saveToFile();
161
+ const terminal = vscode.window.createTerminal('TypeCAD Debug');
162
+ terminal.show();
163
+ terminal.sendText('npx cuttlefish build --debug');
164
+ }
165
+ /**
166
+ * Sync breakpoints from VSCode's built-in breakpoint system.
167
+ * Captures conditional breakpoints and logpoints.
168
+ * REPLACES all breakpoints with the current VS Code state.
169
+ */
170
+ syncFromVSCode() {
171
+ const vscodeBreakpoints = vscode.debug.breakpoints;
172
+ console.log(`TypeCAD: Syncing ${vscodeBreakpoints.length} breakpoints from VS Code`);
173
+ this.breakpoints.clear();
174
+ let count = 0;
175
+ for (const bp of vscodeBreakpoints) {
176
+ if (bp instanceof vscode.SourceBreakpoint) {
177
+ // Key the in-memory map by basename so saveToFile and the toggle path
178
+ // agree on a single canonical key. The loader matches by basename.
179
+ const filePath = bp.location.uri.fsPath;
180
+ const fileName = path.basename(filePath);
181
+ const line = bp.location.range.start.line + 1; // 1-indexed
182
+ if (!this.breakpoints.has(fileName)) {
183
+ this.breakpoints.set(fileName, new Map());
184
+ }
185
+ this.breakpoints.get(fileName).set(line, {
186
+ file: fileName,
187
+ line,
188
+ condition: bp.condition,
189
+ logMessage: bp.logMessage, // LogMessageBreakpoint has this property
190
+ });
191
+ count++;
192
+ }
193
+ }
194
+ this.saveToFile();
195
+ vscode.window.setStatusBarMessage(`TypeCAD: Synced ${count} breakpoints`, 3000);
196
+ console.log(`TypeCAD: Synced ${count} breakpoints to file`);
197
+ }
198
+ /**
199
+ * Load breakpoints from .cuttlefish/breakpoints.json
200
+ */
201
+ loadFromFile() {
202
+ const workspaceFolders = vscode.workspace.workspaceFolders;
203
+ if (!workspaceFolders || workspaceFolders.length === 0)
204
+ return;
205
+ const filePath = path.join(workspaceFolders[0].uri.fsPath, BREAKPOINTS_DIR, BREAKPOINTS_FILE);
206
+ if (!fs.existsSync(filePath))
207
+ return;
208
+ try {
209
+ const content = fs.readFileSync(filePath, 'utf8');
210
+ const map = JSON.parse(content);
211
+ for (const bp of map.breakpoints ?? []) {
212
+ if (!this.breakpoints.has(bp.file)) {
213
+ this.breakpoints.set(bp.file, new Map());
214
+ }
215
+ this.breakpoints.get(bp.file).set(bp.line, bp);
216
+ }
217
+ }
218
+ catch (err) {
219
+ console.error('TypeCAD: Failed to load breakpoints:', err);
220
+ }
221
+ }
222
+ /**
223
+ * Save breakpoints to .cuttlefish/breakpoints.json atomically.
224
+ * Writes to a temp file then renames, so a watching transpiler never reads
225
+ * a half-written file.
226
+ */
227
+ saveToFile() {
228
+ const workspaceFolders = vscode.workspace.workspaceFolders;
229
+ if (!workspaceFolders || workspaceFolders.length === 0) {
230
+ console.log('TypeCAD: No workspace folder, skipping save');
231
+ return;
232
+ }
233
+ const dirPath = path.join(workspaceFolders[0].uri.fsPath, BREAKPOINTS_DIR);
234
+ const filePath = path.join(dirPath, BREAKPOINTS_FILE);
235
+ const tmpPath = `${filePath}.tmp`;
236
+ try {
237
+ if (!fs.existsSync(dirPath)) {
238
+ fs.mkdirSync(dirPath, { recursive: true });
239
+ }
240
+ }
241
+ catch (mkdirErr) {
242
+ console.error('TypeCAD: Failed to create directory:', mkdirErr);
243
+ vscode.window.showErrorMessage(`TypeCAD: Failed to create ${BREAKPOINTS_DIR} directory: ${mkdirErr}`);
244
+ return;
245
+ }
246
+ const map = { breakpoints: [] };
247
+ for (const [, fileBreakpoints] of this.breakpoints) {
248
+ for (const [, bp] of fileBreakpoints) {
249
+ map.breakpoints.push(bp);
250
+ }
251
+ }
252
+ // Stable order for clean diffs and reproducible output.
253
+ map.breakpoints.sort((a, b) => {
254
+ if (a.file !== b.file)
255
+ return a.file.localeCompare(b.file);
256
+ return a.line - b.line;
257
+ });
258
+ try {
259
+ fs.writeFileSync(tmpPath, JSON.stringify(map, null, 2));
260
+ fs.renameSync(tmpPath, filePath);
261
+ console.log(`TypeCAD: Saved ${map.breakpoints.length} breakpoints to ${filePath}`);
262
+ }
263
+ catch (err) {
264
+ // Best effort: clean up the temp file on failure.
265
+ try {
266
+ fs.unlinkSync(tmpPath);
267
+ }
268
+ catch { }
269
+ console.error('TypeCAD: Failed to save breakpoints:', err);
270
+ vscode.window.showErrorMessage(`TypeCAD: Failed to save breakpoints: ${err}`);
271
+ }
272
+ }
273
+ dispose() {
274
+ this._onDidChange.dispose();
275
+ }
276
+ }
277
+ // ---------------------------------------------------------------------------
278
+ // Declaration Generator
279
+ // ---------------------------------------------------------------------------
280
+ class DeclarationGenerator {
281
+ /**
282
+ * Generate a .d.ts sidecar for a C++ file if one is not already present.
283
+ */
284
+ async checkAndGenerate(cppPath) {
285
+ const declPath = cppPath.replace(/\.cpp$/i, '.d.ts');
286
+ if (fs.existsSync(declPath)) {
287
+ return; // Already exists — never clobber.
288
+ }
289
+ const result = await this.generateDeclaration(cppPath, declPath);
290
+ if (result) {
291
+ vscode.window.showInformationMessage(`TypeCAD: Generated ${path.basename(declPath)} from ${path.basename(cppPath)}. Review and adjust types if needed.`);
292
+ }
293
+ }
294
+ /**
295
+ * Generate a declaration for the currently active C++ file.
296
+ */
297
+ async generateForCurrentFile() {
298
+ const editor = vscode.window.activeTextEditor;
299
+ if (!editor) {
300
+ vscode.window.showErrorMessage('TypeCAD: No active editor');
301
+ return;
302
+ }
303
+ const filePath = editor.document.uri.fsPath;
304
+ if (!filePath.endsWith('.cpp')) {
305
+ vscode.window.showErrorMessage('TypeCAD: Active file must be a .cpp file');
306
+ return;
307
+ }
308
+ const declPath = filePath.replace(/\.cpp$/i, '.d.ts');
309
+ const result = await this.generateDeclaration(filePath, declPath);
310
+ if (result) {
311
+ vscode.window.showInformationMessage(`TypeCAD: Generated ${path.basename(declPath)}`);
312
+ const doc = await vscode.workspace.openTextDocument(result);
313
+ await vscode.window.showTextDocument(doc);
314
+ }
315
+ else {
316
+ vscode.window.showWarningMessage('TypeCAD: No classes or constants found in C++ file');
317
+ }
318
+ }
319
+ /**
320
+ * Generate a .d.ts file from a C++ file via the cuttlefish CLI.
321
+ * Uses the monorepo source directly when developing inside this repo,
322
+ * falls back to `npx cuttlefish` for installed users.
323
+ */
324
+ async generateDeclaration(cppPath, declPath) {
325
+ return new Promise((resolve) => {
326
+ const workspaceFolders = vscode.workspace.workspaceFolders;
327
+ // Local-CLI fallback for development inside the typecode monorepo.
328
+ const localCliPath = workspaceFolders
329
+ ? path.join(workspaceFolders[0].uri.fsPath, 'packages/cuttlefish/src/cli.ts')
330
+ : null;
331
+ const cmd = localCliPath && fs.existsSync(localCliPath)
332
+ ? `npx tsx "${localCliPath}" gen-decls "${cppPath}"`
333
+ : `npx cuttlefish gen-decls "${cppPath}"`;
334
+ (0, node_child_process_1.exec)(cmd, { cwd: workspaceFolders?.[0]?.uri.fsPath }, (error) => {
335
+ if (error) {
336
+ console.error('TypeCAD: Failed to generate declaration:', error);
337
+ vscode.window.showErrorMessage(`TypeCAD: Failed to generate declaration: ${error.message}`);
338
+ resolve(null);
339
+ return;
340
+ }
341
+ resolve(fs.existsSync(declPath) ? declPath : null);
342
+ });
343
+ });
344
+ }
345
+ dispose() { }
346
+ }
347
+ //# sourceMappingURL=extension.js.map