@typecad/cuttlefish 1.0.0-alpha.14 → 1.0.0-alpha.16

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 (315) hide show
  1. package/README.md +82 -79
  2. package/assets/editor-extensions/typecad-debug/README.md +25 -26
  3. package/dist/api/config.d.ts +22 -26
  4. package/dist/api/schema/types.d.ts +20 -3
  5. package/dist/api/shared/async-runtime-static.d.ts +1 -1
  6. package/dist/api/shared/async-runtime-static.js +5 -5
  7. package/dist/api/shared/async-types.d.ts +3 -2
  8. package/dist/api/shared/board-catalog.d.ts +2 -0
  9. package/dist/api/shared/board-catalog.js +6 -0
  10. package/dist/api/shared/board-resolver.d.ts +4 -7
  11. package/dist/api/shared/board-resolver.js +2 -1
  12. package/dist/api/shared/coop-scheduler.d.ts +1 -1
  13. package/dist/api/shared/coop-scheduler.js +1 -1
  14. package/dist/api/shared/cpp-type-ir.d.ts +1 -1
  15. package/dist/api/shared/cpp-type-ir.js +1 -1
  16. package/dist/api/shared/display-profile.d.ts +1 -1
  17. package/dist/api/shared/display-profile.js +3 -5
  18. package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
  19. package/dist/api/shared/framework-manifest-registry.js +0 -1
  20. package/dist/api/shared/framework-manifest.d.ts +7 -6
  21. package/dist/api/shared/framework-manifest.js +6 -11
  22. package/dist/api/shared/hal-op-ir.d.ts +294 -685
  23. package/dist/api/shared/hal-op-ir.js +31 -65
  24. package/dist/api/shared/index.d.ts +0 -4
  25. package/dist/api/shared/index.js +1 -7
  26. package/dist/api/shared/ir-core.d.ts +6 -0
  27. package/dist/api/shared/ir-declarations.d.ts +4 -0
  28. package/dist/api/shared/ir.d.ts +1 -3
  29. package/dist/api/shared/platform-strategy.d.ts +14 -37
  30. package/dist/api/shared/polyfill-helper-registry.js +0 -5
  31. package/dist/api/shared/polyfill-types.js +0 -27
  32. package/dist/api/shared/promise-runtime.js +3 -3
  33. package/dist/api/shared/spdx-licenses.d.ts +12 -10
  34. package/dist/api/shared/spdx-licenses.js +1 -1
  35. package/dist/api/shared/toolchain-types.d.ts +1 -1
  36. package/dist/api/shared/toolchain-types.js +3 -3
  37. package/dist/api/shared/types.d.ts +0 -3
  38. package/dist/api/shared/validate-framework-manifest.js +13 -33
  39. package/dist/board-catalog/dts-reader.d.ts +220 -0
  40. package/dist/board-catalog/dts-reader.js +1052 -0
  41. package/dist/board-catalog/index.d.ts +11 -0
  42. package/dist/board-catalog/index.js +12 -0
  43. package/dist/board-catalog/pinconfig.d.ts +48 -0
  44. package/dist/board-catalog/pinconfig.js +263 -0
  45. package/dist/board-catalog/sdk.d.ts +82 -0
  46. package/dist/board-catalog/sdk.js +180 -0
  47. package/dist/board-catalog/store.d.ts +196 -0
  48. package/dist/board-catalog/store.js +363 -0
  49. package/dist/board-catalog/types.d.ts +233 -0
  50. package/dist/board-catalog/types.js +7 -0
  51. package/dist/board-catalog/walker.d.ts +112 -0
  52. package/dist/board-catalog/walker.js +1101 -0
  53. package/dist/cli-utils.d.ts +2 -2
  54. package/dist/cli-utils.js +5 -5
  55. package/dist/cli.js +219 -242
  56. package/dist/config-loader.d.ts +14 -19
  57. package/dist/config-loader.js +240 -78
  58. package/dist/config-schema.d.ts +3 -5
  59. package/dist/config-schema.js +8 -8
  60. package/dist/contract/board-generator.d.ts +4 -4
  61. package/dist/contract/board-generator.js +16 -5
  62. package/dist/contract/contract-parser.d.ts +27 -0
  63. package/dist/contract/contract-parser.js +76 -0
  64. package/dist/contract/index.d.ts +1 -1
  65. package/dist/contract/index.js +70 -21
  66. package/dist/create/active-board-catalog.d.ts +9 -0
  67. package/dist/create/active-board-catalog.js +94 -0
  68. package/dist/create/board-catalog.generated.d.ts +96 -0
  69. package/dist/create/board-catalog.generated.js +128737 -0
  70. package/dist/create/board-search.d.ts +23 -0
  71. package/dist/create/board-search.js +88 -0
  72. package/dist/create/editor-integration.d.ts +4 -2
  73. package/dist/create/editor-integration.js +41 -2
  74. package/dist/create/framework-catalog.d.ts +57 -9
  75. package/dist/create/framework-catalog.js +76 -57
  76. package/dist/create/index.d.ts +5 -11
  77. package/dist/create/index.js +3 -8
  78. package/dist/create/mcu-target.d.ts +39 -0
  79. package/dist/create/mcu-target.js +80 -0
  80. package/dist/create/pack-targets.d.ts +19 -0
  81. package/dist/create/pack-targets.js +56 -0
  82. package/dist/create/scaffold.d.ts +4 -7
  83. package/dist/create/scaffold.js +19 -109
  84. package/dist/create/templates.d.ts +32 -5
  85. package/dist/create/templates.js +130 -116
  86. package/dist/create/wizard.d.ts +12 -1
  87. package/dist/create/wizard.js +168 -38
  88. package/dist/debug/preprocessor.d.ts +5 -0
  89. package/dist/debug/preprocessor.js +31 -7
  90. package/dist/diagnostics/diagnostics-report.d.ts +1 -1
  91. package/dist/diagnostics/diagnostics-report.js +3 -11
  92. package/dist/diagnostics/json-schema.d.ts +1 -1
  93. package/dist/diagnostics/md-writer.js +2 -2
  94. package/dist/diagnostics/mermaid-builder.d.ts +1 -1
  95. package/dist/diagnostics/mermaid-builder.js +1 -1
  96. package/dist/emit/cpp-emitter.js +4 -1
  97. package/dist/emit/emitters/class-emitter.js +32 -4
  98. package/dist/emit/emitters/emitter-context.d.ts +11 -0
  99. package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
  100. package/dist/emit/emitters/function-emitter-impl.js +33 -17
  101. package/dist/emit/emitters/output-finalizer.d.ts +7 -0
  102. package/dist/emit/emitters/output-finalizer.js +31 -23
  103. package/dist/emit/emitters/setup.js +125 -63
  104. package/dist/emit/emitters/top-level-prep.js +1 -1
  105. package/dist/emit/emitters/type-decl-emitter.js +13 -8
  106. package/dist/emit/emitters/ui-emitter.js +1 -1
  107. package/dist/emit/expression-renderer.d.ts +3 -3
  108. package/dist/emit/expression-renderer.js +17 -7
  109. package/dist/emit/route-hal-op.js +17 -48
  110. package/dist/emit/snprintf-helpers.d.ts +1 -3
  111. package/dist/emit/snprintf-helpers.js +1 -39
  112. package/dist/emit/statement-renderer.d.ts +0 -4
  113. package/dist/emit/statement-renderer.js +54 -45
  114. package/dist/emit/utils/async-state-machine.d.ts +16 -9
  115. package/dist/emit/utils/async-state-machine.js +56 -54
  116. package/dist/emit/utils/comment-helpers.d.ts +0 -8
  117. package/dist/emit/utils/comment-helpers.js +1 -1
  118. package/dist/emit/utils/cpp-helpers.d.ts +2 -2
  119. package/dist/emit/utils/cpp-helpers.js +2 -2
  120. package/dist/emit/utils/hal-op-cpp-type.js +4 -6
  121. package/dist/emit/utils/index.d.ts +3 -3
  122. package/dist/emit/utils/index.js +3 -3
  123. package/dist/emit/utils/type-inference.d.ts +1 -29
  124. package/dist/emit/utils/type-inference.js +0 -75
  125. package/dist/framework-package.d.ts +3 -0
  126. package/dist/framework-package.js +23 -6
  127. package/dist/framework-registry.d.ts +5 -5
  128. package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
  129. package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
  130. package/dist/frameworks/native/index.d.ts +3 -0
  131. package/dist/frameworks/native/index.js +15 -0
  132. package/dist/frameworks/native/native-compile.d.ts +17 -0
  133. package/dist/frameworks/native/native-compile.js +170 -0
  134. package/dist/frameworks/native/native-config.d.ts +41 -0
  135. package/dist/frameworks/native/native-config.js +7 -0
  136. package/dist/frameworks/native/strategy.d.ts +97 -0
  137. package/dist/frameworks/native/strategy.js +664 -0
  138. package/dist/ir/board-resolver.d.ts +18 -23
  139. package/dist/ir/board-resolver.js +43 -401
  140. package/dist/ir/build-ir-state.d.ts +3 -0
  141. package/dist/ir/build-ir-state.js +42 -0
  142. package/dist/ir/build-ir.d.ts +1 -1
  143. package/dist/ir/build-ir.js +40 -42
  144. package/dist/ir/declaration-builders.js +1 -0
  145. package/dist/ir/expression-to-ir.js +17 -10
  146. package/dist/ir/hal/hal-emitter.d.ts +0 -2
  147. package/dist/ir/hal/hal-emitter.js +92 -41
  148. package/dist/ir/hal/hal-parser.d.ts +5 -5
  149. package/dist/ir/hal/hal-parser.js +128 -36
  150. package/dist/ir/hal/hal-plugins.d.ts +0 -1
  151. package/dist/ir/hal/hal-plugins.js +425 -716
  152. package/dist/ir/heap-analysis.js +2 -41
  153. package/dist/ir/identifier-collector.js +32 -20
  154. package/dist/ir/network-validation.js +7 -11
  155. package/dist/ir/ownership-analysis.js +75 -13
  156. package/dist/ir/peripheral-usage.d.ts +8 -2
  157. package/dist/ir/peripheral-usage.js +78 -149
  158. package/dist/ir/peripheral-validation.js +23 -3
  159. package/dist/ir/pin-capability-validation.d.ts +12 -0
  160. package/dist/ir/pin-capability-validation.js +61 -97
  161. package/dist/ir/pin-mode-validation.js +5 -5
  162. package/dist/ir/program-analysis.d.ts +8 -15
  163. package/dist/ir/program-analysis.js +140 -323
  164. package/dist/ir/pulldown-validation.js +11 -4
  165. package/dist/ir/resource-analysis.js +15 -3
  166. package/dist/ir/statement-to-ir.js +0 -6
  167. package/dist/ir/timing-validation.js +1 -1
  168. package/dist/ir/transformers/array-methods.js +11 -5
  169. package/dist/ir/transformers/call-statement.js +20 -87
  170. package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
  171. package/dist/ir/transformers/callback-context-registry.js +8 -16
  172. package/dist/ir/transformers/control-flow.js +0 -13
  173. package/dist/ir/transformers/expressions.js +10 -9
  174. package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
  175. package/dist/ir/transformers/hal-call-resolver.js +24 -10
  176. package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
  177. package/dist/ir/transformers/hal-emit-helpers.js +2 -2
  178. package/dist/ir/transformers/namespace-methods.js +1 -1
  179. package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
  180. package/dist/ir/transformers/ui-callback-lowering.js +0 -24
  181. package/dist/ir/transformers/variables.js +338 -42
  182. package/dist/ir/try-catch-validation.js +4 -3
  183. package/dist/ir/type-resolution.js +15 -4
  184. package/dist/ir/validation-orchestrator.js +0 -9
  185. package/dist/libdef/cpp-to-decl.d.ts +0 -9
  186. package/dist/libdef/cpp-to-decl.js +0 -72
  187. package/dist/libdef/registry.d.ts +0 -1
  188. package/dist/libdef/registry.js +1 -24
  189. package/dist/library/init.d.ts +1 -1
  190. package/dist/library/init.js +137 -137
  191. package/dist/library-packages.d.ts +1 -1
  192. package/dist/library-packages.js +1 -1
  193. package/dist/mapping/peripheral-names.js +9 -4
  194. package/dist/mapping/source-map.d.ts +3 -4
  195. package/dist/mapping/source-map.js +12 -18
  196. package/dist/orchestrator/graph-builder.d.ts +3 -3
  197. package/dist/orchestrator/graph-builder.js +13 -12
  198. package/dist/orchestrator/type-checker.d.ts +3 -3
  199. package/dist/orchestrator/type-checker.js +3 -3
  200. package/dist/platform/async-runtime.js +1 -1
  201. package/dist/platform/coop-scheduler-runtime.js +2 -2
  202. package/dist/platform/generic-debug-codegen.d.ts +36 -0
  203. package/dist/platform/generic-debug-codegen.js +185 -0
  204. package/dist/platform/generic-strategy.d.ts +3 -4
  205. package/dist/platform/generic-strategy.js +5 -80
  206. package/dist/platform/index.js +1 -1
  207. package/dist/platform/registry.d.ts +2 -2
  208. package/dist/platform/registry.js +2 -2
  209. package/dist/safety/asil-decorators.d.ts +32 -0
  210. package/dist/safety/asil-decorators.js +32 -0
  211. package/dist/safety/authoring.d.ts +85 -0
  212. package/dist/safety/authoring.js +61 -0
  213. package/dist/safety/engine.d.ts +3 -0
  214. package/dist/safety/engine.js +83 -0
  215. package/dist/safety/hal/ops.d.ts +48 -0
  216. package/dist/safety/hal/ops.js +46 -0
  217. package/dist/safety/iso26262/analyze.d.ts +13 -0
  218. package/dist/safety/iso26262/analyze.js +29 -0
  219. package/dist/safety/iso26262/asil.d.ts +10 -0
  220. package/dist/safety/iso26262/asil.js +22 -0
  221. package/dist/safety/iso26262/collect.d.ts +14 -0
  222. package/dist/safety/iso26262/collect.js +137 -0
  223. package/dist/safety/iso26262/goto-checker.d.ts +10 -0
  224. package/dist/safety/iso26262/goto-checker.js +72 -0
  225. package/dist/safety/iso26262/heap-checker.d.ts +7 -0
  226. package/dist/safety/iso26262/heap-checker.js +57 -0
  227. package/dist/safety/iso26262/init-checker.d.ts +13 -0
  228. package/dist/safety/iso26262/init-checker.js +127 -0
  229. package/dist/safety/iso26262/loop-checker.d.ts +7 -0
  230. package/dist/safety/iso26262/loop-checker.js +86 -0
  231. package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
  232. package/dist/safety/iso26262/recursion-checker.js +134 -0
  233. package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
  234. package/dist/safety/iso26262/sidecar-writer.js +13 -0
  235. package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
  236. package/dist/safety/passes/pinMode-intercept.js +60 -0
  237. package/dist/safety/runtime/mode-table.d.ts +5 -0
  238. package/dist/safety/runtime/mode-table.js +55 -0
  239. package/dist/safety/runtime/polyfills.d.ts +6 -0
  240. package/dist/safety/runtime/polyfills.js +12 -0
  241. package/dist/safety/runtime/result-struct.d.ts +11 -0
  242. package/dist/safety/runtime/result-struct.js +98 -0
  243. package/dist/safety/runtime/safe-int.d.ts +33 -0
  244. package/dist/safety/runtime/safe-int.js +170 -0
  245. package/dist/safety/runtime/safe-traits.d.ts +4 -0
  246. package/dist/safety/runtime/safe-traits.js +95 -0
  247. package/dist/safety/runtime/safe-variable.d.ts +39 -0
  248. package/dist/safety/runtime/safe-variable.js +226 -0
  249. package/dist/safety/runtime/vote.d.ts +8 -0
  250. package/dist/safety/runtime/vote.js +92 -0
  251. package/dist/safety/runtime/write-verify.d.ts +8 -0
  252. package/dist/safety/runtime/write-verify.js +71 -0
  253. package/dist/safety/safe-int-types.d.ts +45 -0
  254. package/dist/safety/safe-int-types.js +25 -0
  255. package/dist/safety/safe-variable-types.d.ts +29 -0
  256. package/dist/safety/safe-variable-types.js +19 -0
  257. package/dist/safety/safety-bridge.d.ts +5 -6
  258. package/dist/safety/safety-bridge.js +15 -28
  259. package/dist/safety/sidecar-bridge.d.ts +1 -3
  260. package/dist/safety/sidecar-bridge.js +3 -20
  261. package/dist/safety/specifiers.d.ts +6 -0
  262. package/dist/safety/specifiers.js +14 -0
  263. package/dist/safety-hook.d.ts +8 -7
  264. package/dist/safety-hook.js +12 -13
  265. package/dist/testing.d.ts +4 -5
  266. package/dist/testing.js +5 -5
  267. package/dist/transpile/resolution.d.ts +1 -1
  268. package/dist/transpile/resolution.js +18 -9
  269. package/dist/transpile/test-pins.d.ts +18 -0
  270. package/dist/transpile/test-pins.js +142 -0
  271. package/dist/transpile.d.ts +1 -2
  272. package/dist/transpile.js +36 -30
  273. package/dist/types.d.ts +26 -26
  274. package/dist/ui-hook.d.ts +1 -1
  275. package/dist/utils/cli.d.ts +2 -2
  276. package/dist/utils/cli.js +92 -154
  277. package/dist/utils/fs.d.ts +3 -4
  278. package/dist/utils/fs.js +4 -5
  279. package/dist/utils/strings.d.ts +0 -1
  280. package/dist/utils/strings.js +0 -8
  281. package/dist/utils/ui.d.ts +5 -2
  282. package/dist/utils/ui.js +13 -3
  283. package/package.json +158 -157
  284. package/dist/add-preset.d.ts +0 -4
  285. package/dist/add-preset.js +0 -74
  286. package/dist/api/shared/async-symbol-detector.d.ts +0 -11
  287. package/dist/api/shared/async-symbol-detector.js +0 -140
  288. package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
  289. package/dist/api/shared/native-display-op-resolver.js +0 -64
  290. package/dist/create/board-checklist.d.ts +0 -2
  291. package/dist/create/board-checklist.js +0 -52
  292. package/dist/create/board-codegen.d.ts +0 -9
  293. package/dist/create/board-codegen.js +0 -238
  294. package/dist/create/board-generators.d.ts +0 -12
  295. package/dist/create/board-generators.js +0 -651
  296. package/dist/create/board-spec.d.ts +0 -181
  297. package/dist/create/board-spec.js +0 -214
  298. package/dist/install/framework-catalog.d.ts +0 -53
  299. package/dist/install/framework-catalog.js +0 -107
  300. package/dist/install/handle-install.d.ts +0 -35
  301. package/dist/install/handle-install.js +0 -177
  302. package/dist/install/index.d.ts +0 -4
  303. package/dist/install/index.js +0 -3
  304. package/dist/ir/pin-state-tracking.d.ts +0 -58
  305. package/dist/ir/pin-state-tracking.js +0 -182
  306. package/dist/ir/pwm-timer-sharing.d.ts +0 -4
  307. package/dist/ir/pwm-timer-sharing.js +0 -94
  308. package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
  309. package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
  310. package/dist/libdef/component-decls.d.ts +0 -2
  311. package/dist/libdef/component-decls.js +0 -6
  312. package/dist/libdef/component-discovery.d.ts +0 -43
  313. package/dist/libdef/component-discovery.js +0 -83
  314. package/dist/theme-tokens.d.ts +0 -22
  315. package/dist/theme-tokens.js +0 -172
@@ -8,7 +8,6 @@ import fs from "node:fs";
8
8
  import path from "node:path";
9
9
  import { parseHeader } from "./header-parser.js";
10
10
  import { buildClassIndex, BaseClassResolver } from "./base-class-resolver.js";
11
- import { writeText } from "../utils/fs.js";
12
11
  /**
13
12
  * Maps C++ types to TypeScript types
14
13
  */
@@ -583,74 +582,3 @@ function generateDeclWithResolver(filePath, resolver) {
583
582
  }
584
583
  return outPath;
585
584
  }
586
- // ─── ESP-IDF component dispatch ───────────────────────────────────────────
587
- //
588
- // Picks the C or C++ emitter per header based on whether it declares classes.
589
- // ESP-IDF components are mostly C (free functions + typedefs); Arduino-style
590
- // libraries are C++ classes. Spec:
591
- // docs/superpowers/specs/2026-07-19-framework-esp32-components-design.md
592
- import { generateCDecl } from "./c-to-decl.js";
593
- import { discoverComponentHeaders } from "./component-discovery.js";
594
- /** Heuristic: does this header declare any C++ classes? */
595
- function hasClasses(headerPath) {
596
- try {
597
- const content = fs.readFileSync(headerPath, "utf8");
598
- return parseHeader(content).length > 0;
599
- }
600
- catch {
601
- return false;
602
- }
603
- }
604
- /**
605
- * Generate .d.ts declarations for every declared component's headers,
606
- * picking the C or C++ emitter per header based on whether it declares classes.
607
- *
608
- * Returns the list of created/updated .d.ts paths (headers that produced no
609
- * declarations are skipped).
610
- */
611
- export function generateComponentDeclsForProject(projectDir, roots) {
612
- const headers = discoverComponentHeaders(projectDir, roots);
613
- const created = [];
614
- for (const discovered of headers) {
615
- // Output path: <outputDir>/<basename>.d.ts. For managed/local this is
616
- // alongside the header; for builtins it's the project-local cache dir.
617
- const baseName = path.basename(discovered.path).replace(/\.h$/i, '');
618
- const outputPath = path.join(discovered.outputDir, baseName + '.d.ts');
619
- const out = hasClasses(discovered.path)
620
- ? generateDecl(discovered.path, outputPath)
621
- : generateCDecl(discovered.path, outputPath);
622
- if (out) {
623
- created.push(out);
624
- // Write a sibling .libdef.json so the import → #include resolver picks
625
- // up the real (case-preserving) header name. Without this, the resolver
626
- // falls back to toPascalCase(moduleKey) + ".h" — fine for Arduino libs
627
- // (Adafruit_GFX → Adafruit_GFX.h, resolved separately) but wrong for
628
- // ESP-IDF component headers (esp_wifi → <EspWifi.h>, not <esp_wifi.h>).
629
- // The libdef declares the actual header basename ("esp_wifi.h"), which
630
- // is the ground truth — the generator just read the file.
631
- writeComponentLibdef(discovered.path, outputPath);
632
- }
633
- }
634
- return created;
635
- }
636
- /**
637
- * Write `<d.ts-basename>.libdef.json` next to a generated component `.d.ts`,
638
- * pointing the import → #include resolver at the actual source header.
639
- *
640
- * The libdef `module` field is the lowercased basename (matches what
641
- * `toModuleKey()` produces from an import specifier), and `include` is the
642
- * case-preserving `<basename>.h` — quote-wrapped because component headers
643
- * are project-local (resolved via the include path), not system angle-bracket
644
- * includes. Matches the local-header convention in `resolveLocalModuleHeader`.
645
- */
646
- function writeComponentLibdef(sourceHeaderPath, dtsOutputPath) {
647
- const headerBaseName = path.basename(sourceHeaderPath); // e.g. "esp_wifi.h"
648
- const dtsBaseName = path.basename(dtsOutputPath, '.d.ts'); // e.g. "esp_wifi"
649
- const libdefPath = path.join(path.dirname(dtsOutputPath), `${dtsBaseName}.libdef.json`);
650
- const libdef = {
651
- module: dtsBaseName.toLowerCase(),
652
- include: `"${headerBaseName}"`,
653
- source: sourceHeaderPath,
654
- };
655
- writeText(libdefPath, JSON.stringify(libdef, null, 2) + '\n');
656
- }
@@ -6,5 +6,4 @@ interface ResolvedImport {
6
6
  }
7
7
  export declare function loadLibraryDefinitions(definitionsDir: string): Map<string, LibraryDefinition>;
8
8
  export declare function resolveImport(importNode: ImportIR, definitions: Map<string, LibraryDefinition>, target: TargetProfile, platformContext?: PlatformContext, importerFilePath?: string): ResolvedImport;
9
- export declare function generateLibdefStubs(inputFile: string, imports: ImportIR[], outDir: string): string[];
10
9
  export {};
@@ -22,8 +22,7 @@ function getLibraryResolver() {
22
22
  export function loadLibraryDefinitions(definitionsDir) {
23
23
  const registry = new Map();
24
24
  // Recursive scan: libdefs may live at the entry dir (single-level convention)
25
- // or nested under cache trees like `.cuttlefish/component-decls/<component>/`
26
- // (per-component overrides generated alongside .d.ts stubs).
25
+ // or nested in project subdirectories (per-module overrides).
27
26
  const files = listFilesRecursive(definitionsDir, ".libdef.json");
28
27
  for (const filePath of files) {
29
28
  let def;
@@ -121,25 +120,3 @@ export function resolveImport(importNode, definitions, target, platformContext,
121
120
  },
122
121
  };
123
122
  }
124
- export function generateLibdefStubs(inputFile, imports, outDir) {
125
- const created = [];
126
- if (!fs.existsSync(outDir)) {
127
- fs.mkdirSync(outDir, { recursive: true });
128
- }
129
- for (const item of imports) {
130
- const moduleKey = toModuleKey(item.moduleSpecifier);
131
- const libdefPath = path.join(outDir, `${moduleKey}.libdef.json`);
132
- if (!fs.existsSync(libdefPath)) {
133
- const include = `<${toPascalCase(moduleKey)}.h>`;
134
- const libdefContent = {
135
- module: moduleKey,
136
- include,
137
- symbols: Object.fromEntries(item.namedImports.map((symbol) => [symbol, symbol])),
138
- source: inputFile,
139
- };
140
- fs.writeFileSync(libdefPath, JSON.stringify(libdefContent, null, 2) + "\n", "utf8");
141
- created.push(libdefPath);
142
- }
143
- }
144
- return created;
145
- }
@@ -1,7 +1,7 @@
1
1
  export interface LibraryInitOptions {
2
2
  /** Full package name (e.g. '@acme/esp32-led-ring' or 'my-lib'). */
3
3
  name?: string;
4
- /** Framework id from FRAMEWORK_CATALOG ('zephyr', 'arduino', ...). */
4
+ /** Framework id from FRAMEWORK_CATALOG ('zephyr', 'native', ...). */
5
5
  framework?: string;
6
6
  /** Category id from LIBRARY_CATEGORIES. */
7
7
  category?: string;
@@ -124,38 +124,38 @@ function renderTsconfig() {
124
124
  }, null, 2) + "\n";
125
125
  }
126
126
  function renderApi(m) {
127
- return `// ---------------------------------------------------------------------------
128
- // ${m.packageName} — cuttlefish library package (${m.category.label.toLowerCase()}).
129
- //
130
- // This file is the typed API contract: it is never executed. The cuttlefish
131
- // transpiler lowers the import to the shim header (shims/__tc_${m.tokenBase}.h),
132
- // and calls on the exported instance render verbatim into the generated C++.
133
- // Two rules keep that contract intact:
134
- //
135
- // 1. Method names are load-bearing. The C++ class in the shim must define
136
- // exactly these names — 'rgbLed'-style call sites appear in the C++ as-is.
137
- // 2. Export a singleton instance, not a constructor. A bare 'new' in user
138
- // code renders as a C++ heap allocation, which the AUTOSAR C++14 rules
139
- // the shims follow forbid.
140
- // ---------------------------------------------------------------------------
141
-
142
- /**
143
- * ${m.category.description} (${m.category.examples}).
144
- */
145
- export class ${m.className} {
146
- /**
147
- * Prepare the hardware. Call once from setup(). The stub in the shim is a
148
- * no-op — replace it with your initialization code.
149
- */
150
- begin(): this {
151
- return this;
152
- }
153
-
154
- // Add your API here. Every method needs a matching member on the C++ class.
155
- }
156
-
157
- /** The instance to use — a preconstructed singleton (see rule 2 above). */
158
- export const ${m.instanceName}: ${m.className} = new ${m.className}();
127
+ return `// ---------------------------------------------------------------------------
128
+ // ${m.packageName} — cuttlefish library package (${m.category.label.toLowerCase()}).
129
+ //
130
+ // This file is the typed API contract: it is never executed. The cuttlefish
131
+ // transpiler lowers the import to the shim header (shims/__tc_${m.tokenBase}.h),
132
+ // and calls on the exported instance render verbatim into the generated C++.
133
+ // Two rules keep that contract intact:
134
+ //
135
+ // 1. Method names are load-bearing. The C++ class in the shim must define
136
+ // exactly these names — 'rgbLed'-style call sites appear in the C++ as-is.
137
+ // 2. Export a singleton instance, not a constructor. A bare 'new' in user
138
+ // code renders as a C++ heap allocation, which the AUTOSAR C++14 rules
139
+ // the shims follow forbid.
140
+ // ---------------------------------------------------------------------------
141
+
142
+ /**
143
+ * ${m.category.description} (${m.category.examples}).
144
+ */
145
+ export class ${m.className} {
146
+ /**
147
+ * Prepare the hardware. Call once from setup(). The stub in the shim is a
148
+ * no-op — replace it with your initialization code.
149
+ */
150
+ begin(): this {
151
+ return this;
152
+ }
153
+
154
+ // Add your API here. Every method needs a matching member on the C++ class.
155
+ }
156
+
157
+ /** The instance to use — a preconstructed singleton (see rule 2 above). */
158
+ export const ${m.instanceName}: ${m.className} = new ${m.className}();
159
159
  `;
160
160
  }
161
161
  function renderManifest(m) {
@@ -180,123 +180,123 @@ function renderManifest(m) {
180
180
  return JSON.stringify(manifest, null, 2) + "\n";
181
181
  }
182
182
  function renderShimHeader(m) {
183
- return `// ---------------------------------------------------------------------------
184
- // __tc_${m.tokenBase}.h — ${m.packageName} shim.
185
- //
186
- // The implementation behind the TypeScript API in src/index.ts. Calls on the
187
- // exported instance render verbatim, so the class name, the instance name,
188
- // and the method names must match src/index.ts exactly.
189
- //
190
- // AUTOSAR C++14 by construction: fixed-width integers, static_cast only (no
191
- // C-style casts), no heap, 'final' on the leaf class. The generated
192
- // application's compliance check runs over these bytes.
193
- // ---------------------------------------------------------------------------
194
-
195
- #ifndef TC_${m.tokenBase.toUpperCase()}_H_
196
- #define TC_${m.tokenBase.toUpperCase()}_H_
197
-
198
- #include <cstdint>
199
- ${m.isZephyr ? "#include <zephyr/kernel.h>\n" : ""}class ${m.className} final
200
- {
201
- public:
202
- ${m.className}& begin();
203
-
204
- private:
205
- bool initialized_ = false;
206
- };
207
-
208
- extern ${m.className} ${m.instanceName};
209
-
210
- #endif // TC_${m.tokenBase.toUpperCase()}_H_
183
+ return `// ---------------------------------------------------------------------------
184
+ // __tc_${m.tokenBase}.h — ${m.packageName} shim.
185
+ //
186
+ // The implementation behind the TypeScript API in src/index.ts. Calls on the
187
+ // exported instance render verbatim, so the class name, the instance name,
188
+ // and the method names must match src/index.ts exactly.
189
+ //
190
+ // AUTOSAR C++14 by construction: fixed-width integers, static_cast only (no
191
+ // C-style casts), no heap, 'final' on the leaf class. The generated
192
+ // application's compliance check runs over these bytes.
193
+ // ---------------------------------------------------------------------------
194
+
195
+ #ifndef TC_${m.tokenBase.toUpperCase()}_H_
196
+ #define TC_${m.tokenBase.toUpperCase()}_H_
197
+
198
+ #include <cstdint>
199
+ ${m.isZephyr ? "#include <zephyr/kernel.h>\n" : ""}class ${m.className} final
200
+ {
201
+ public:
202
+ ${m.className}& begin();
203
+
204
+ private:
205
+ bool initialized_ = false;
206
+ };
207
+
208
+ extern ${m.className} ${m.instanceName};
209
+
210
+ #endif // TC_${m.tokenBase.toUpperCase()}_H_
211
211
  `;
212
212
  }
213
213
  function renderShimSource(m) {
214
- return `// ---------------------------------------------------------------------------
215
- // __tc_${m.tokenBase}.cpp — ${m.packageName} shim implementation.
216
- // See __tc_${m.tokenBase}.h for the contract. AUTOSAR C++14 compliant.
217
- // ---------------------------------------------------------------------------
218
-
219
- #include "__tc_${m.tokenBase}.h"
220
-
221
- ${m.className}& ${m.className}::begin()
222
- {
223
- initialized_ = true;
224
- return *this;
225
- }
226
-
227
- ${m.className} ${m.instanceName};
214
+ return `// ---------------------------------------------------------------------------
215
+ // __tc_${m.tokenBase}.cpp — ${m.packageName} shim implementation.
216
+ // See __tc_${m.tokenBase}.h for the contract. AUTOSAR C++14 compliant.
217
+ // ---------------------------------------------------------------------------
218
+
219
+ #include "__tc_${m.tokenBase}.h"
220
+
221
+ ${m.className}& ${m.className}::begin()
222
+ {
223
+ initialized_ = true;
224
+ return *this;
225
+ }
226
+
227
+ ${m.className} ${m.instanceName};
228
228
  `;
229
229
  }
230
230
  function renderOverlay(m) {
231
- return `/*
232
- * ${m.id} — devicetree overlay fragment (${m.category.label.toLowerCase()}).
233
- *
234
- * Appended to the generated boards/<board>.overlay when this library's import
235
- * is used. Describe the hardware here: controllers, pins, binding properties.
236
- * When upstream Zephyr ships a sample overlay for your part, adapt it and
237
- * credit it in a comment.
238
- */
239
-
240
- / {
241
- \t/* aliases { your-alias = &your_node; }; */
242
- };
231
+ return `/*
232
+ * ${m.id} — devicetree overlay fragment (${m.category.label.toLowerCase()}).
233
+ *
234
+ * Appended to the generated boards/<board>.overlay when this library's import
235
+ * is used. Describe the hardware here: controllers, pins, binding properties.
236
+ * When upstream Zephyr ships a sample overlay for your part, adapt it and
237
+ * credit it in a comment.
238
+ */
239
+
240
+ / {
241
+ \t/* aliases { your-alias = &your_node; }; */
242
+ };
243
243
  `;
244
244
  }
245
245
  function renderReadme(m) {
246
- return `# ${m.packageName}
247
-
248
- A cuttlefish library package — ${m.category.label.toLowerCase()} (${m.category.description}),
249
- for the **${m.framework}** framework${m.targets.length > 0 ? ` (targets: ${m.targets.join(", ")})` : ""}.
250
-
251
- ## Use it
252
-
253
- \`\`\`ts
254
- import { ${m.instanceName} } from '${m.packageName}';
255
-
256
- ${m.instanceName}.begin();
257
- \`\`\`
258
-
259
- ## Carry the hardware facts
260
-
261
- This library owns the facts so projects don't have to. Document, in this
262
- README, everything a user would otherwise hunt through datasheets for:
263
-
264
- - which board revisions and targets are supported (and which pins they use),
265
- - which peripherals the library borrows (say so — a user may want them),
266
- - wiring requirements (I2C address straps, level shifting, pull-ups).
267
-
268
- ## Authoring checklist
269
-
270
- - Method names in src/index.ts match the C++ shim names exactly; calls render verbatim.
271
- - Export a singleton instance, not a constructor.
272
- - Shims pass \`cuttlefish library validate\` (AUTOSAR C++14, strict).
273
- - \`cuttlefish.library.json\` declares framework${m.isZephyr ? ", kconfig, overlay" : ""} and the shim files.
274
- - package.json keywords include the marker (\`cuttlefish-library\`) and category (\`cuttlefish-${m.category.id}\`) keywords.
275
-
276
- Validate with \`cuttlefish library validate .\` from this directory.
246
+ return `# ${m.packageName}
247
+
248
+ A cuttlefish library package — ${m.category.label.toLowerCase()} (${m.category.description}),
249
+ for the **${m.framework}** framework${m.targets.length > 0 ? ` (targets: ${m.targets.join(", ")})` : ""}.
250
+
251
+ ## Use it
252
+
253
+ \`\`\`ts
254
+ import { ${m.instanceName} } from '${m.packageName}';
255
+
256
+ ${m.instanceName}.begin();
257
+ \`\`\`
258
+
259
+ ## Carry the hardware facts
260
+
261
+ This library owns the facts so projects don't have to. Document, in this
262
+ README, everything a user would otherwise hunt through datasheets for:
263
+
264
+ - which board revisions and targets are supported (and which pins they use),
265
+ - which peripherals the library borrows (say so — a user may want them),
266
+ - wiring requirements (I2C address straps, level shifting, pull-ups).
267
+
268
+ ## Authoring checklist
269
+
270
+ - Method names in src/index.ts match the C++ shim names exactly; calls render verbatim.
271
+ - Export a singleton instance, not a constructor.
272
+ - Shims pass \`cuttlefish library validate\` (AUTOSAR C++14, strict).
273
+ - \`cuttlefish.library.json\` declares framework${m.isZephyr ? ", kconfig, overlay" : ""} and the shim files.
274
+ - package.json keywords include the marker (\`cuttlefish-library\`) and category (\`cuttlefish-${m.category.id}\`) keywords.
275
+
276
+ Validate with \`cuttlefish library validate .\` from this directory.
277
277
  `;
278
278
  }
279
279
  function renderStarterTest(m) {
280
- return `import { describe, it, expect } from "vitest";
281
- import { readFileSync } from "node:fs";
282
- import { join, dirname } from "node:path";
283
- import { fileURLToPath } from "node:url";
284
- import { ComplianceContext, runSelfCheck } from "@typecad/cuttlefish/compliance";
285
-
286
- // The shipped shim bytes must pass --autosar=strict, exactly like framework
287
- // shims — the generated application's compliance check runs over them.
288
-
289
- const here = dirname(fileURLToPath(import.meta.url));
290
-
291
- describe("${m.packageName} shims under --autosar=strict", () => {
292
- it("__tc_${m.tokenBase}.h/.cpp produce no unrecorded AUTOSAR violations", () => {
293
- const header = readFileSync(join(here, "..", "shims", "__tc_${m.tokenBase}.h"), "utf8").split("\\n");
294
- const source = readFileSync(join(here, "..", "shims", "__tc_${m.tokenBase}.cpp"), "utf8").split("\\n");
295
- const ctx = new ComplianceContext("strict");
296
- const findings = runSelfCheck(ctx, source, header);
297
- expect(findings).toEqual([]);
298
- });
299
- });
280
+ return `import { describe, it, expect } from "vitest";
281
+ import { readFileSync } from "node:fs";
282
+ import { join, dirname } from "node:path";
283
+ import { fileURLToPath } from "node:url";
284
+ import { ComplianceContext, runSelfCheck } from "@typecad/cuttlefish/compliance";
285
+
286
+ // The shipped shim bytes must pass --autosar=strict, exactly like framework
287
+ // shims — the generated application's compliance check runs over them.
288
+
289
+ const here = dirname(fileURLToPath(import.meta.url));
290
+
291
+ describe("${m.packageName} shims under --autosar=strict", () => {
292
+ it("__tc_${m.tokenBase}.h/.cpp produce no unrecorded AUTOSAR violations", () => {
293
+ const header = readFileSync(join(here, "..", "shims", "__tc_${m.tokenBase}.h"), "utf8").split("\\n");
294
+ const source = readFileSync(join(here, "..", "shims", "__tc_${m.tokenBase}.cpp"), "utf8").split("\\n");
295
+ const ctx = new ComplianceContext("strict");
296
+ const findings = runSelfCheck(ctx, source, header);
297
+ expect(findings).toEqual([]);
298
+ });
299
+ });
300
300
  `;
301
301
  }
302
302
  // ── Scaffolding ─────────────────────────────────────────────────────────────
@@ -79,7 +79,7 @@ export declare function validateCuttlefishLibraries(frameworkId: string, buildTa
79
79
  *
80
80
  * 1. scan the emitted sources for each library's gate token;
81
81
  * 2. write (write-if-changed) the shims of every gated library into the
82
- * emitted source directory — the framework scaffold's CMake/sketch
82
+ * emitted source directory — the framework scaffold's CMake/program
83
83
  * regen picks the sources up automatically;
84
84
  * 3. delete shim files recorded in the previous sidecar that are no longer
85
85
  * used, so removing an import removes its native code;
@@ -212,7 +212,7 @@ function readSidecar(sidecarPath) {
212
212
  *
213
213
  * 1. scan the emitted sources for each library's gate token;
214
214
  * 2. write (write-if-changed) the shims of every gated library into the
215
- * emitted source directory — the framework scaffold's CMake/sketch
215
+ * emitted source directory — the framework scaffold's CMake/program
216
216
  * regen picks the sources up automatically;
217
217
  * 3. delete shim files recorded in the previous sidecar that are no longer
218
218
  * used, so removing an import removes its native code;
@@ -20,14 +20,19 @@ export function mapPeripheralName(name, strategy) {
20
20
  if (mapped)
21
21
  return mapped;
22
22
  }
23
- // Default fallbacks if strategy doesn't provide a mapping
23
+ // Default fallbacks if strategy doesn't provide a mapping: the canonical
24
+ // TypeCAD controller names. (The Arduino object names — Serial/Wire/SPI —
25
+ // went with framework-arduino; every live consumer only parses the
26
+ // trailing controller digit, which the canonical names carry too.)
24
27
  const canonical = name.toUpperCase();
25
28
  if (canonical === "UART0")
26
- return "Serial";
29
+ return "UART0";
27
30
  if (canonical === "I2C0")
28
- return "Wire";
31
+ return "I2C0";
29
32
  if (canonical === "SPI0")
30
- return "SPI";
33
+ return "SPI0";
34
+ if (canonical === "USB0")
35
+ return "USB0";
31
36
  return undefined;
32
37
  }
33
38
  // ---------------------------------------------------------------------------
@@ -3,12 +3,11 @@ export declare function writeSourceMap(map: GeneratedSourceMap): string;
3
3
  export declare function readSourceMap(mapPath: string): GeneratedSourceMap;
4
4
  export declare function makeGeneratedMap(generatedFilePath: string, sourceFilePath: string, entries: SourceMapEntry[]): GeneratedSourceMap;
5
5
  export declare function mapCppLocationToTs(map: GeneratedSourceMap, cppLine: number, cppColumn: number, message?: string, cppFilePath?: string): MappedDiagnostic;
6
- export declare function resolveMapPath(mapFileOrGeneratedFile: string): string;
7
6
  /**
8
- * Resolve source map path for a flattened Arduino sketch
9
- * When a sketch is flattened, the source map needs to account for merged files
7
+ * Resolve source map path for a generated program
8
+ * When a program is flattened, the source map needs to account for merged files
10
9
  */
11
- export declare function resolveSourceMapForSketch(sketchPath: string, originalSourceMapPath?: string): string | undefined;
10
+ export declare function resolveSourceMapForProgram(programPath: string, originalSourceMapPath?: string): string | undefined;
12
11
  /**
13
12
  * Index of every per-file source map in a build directory, keyed by the
14
13
  * normalized generated file path (the .cpp/.h each map covers).
@@ -80,42 +80,36 @@ export function mapCppLocationToTs(map, cppLine, cppColumn, message, cppFilePath
80
80
  symbolName: best?.symbolName,
81
81
  };
82
82
  }
83
- export function resolveMapPath(mapFileOrGeneratedFile) {
84
- if (mapFileOrGeneratedFile.endsWith(".thcppmap.json")) {
85
- return path.resolve(process.cwd(), mapFileOrGeneratedFile);
86
- }
87
- return toSourceMapPath(path.resolve(process.cwd(), mapFileOrGeneratedFile));
88
- }
89
83
  /**
90
- * Resolve source map path for a flattened Arduino sketch
91
- * When a sketch is flattened, the source map needs to account for merged files
84
+ * Resolve source map path for a generated program
85
+ * When a program is flattened, the source map needs to account for merged files
92
86
  */
93
- export function resolveSourceMapForSketch(sketchPath, originalSourceMapPath) {
94
- const sketchDir = path.dirname(sketchPath);
95
- const sketchName = path.basename(sketchPath, path.extname(sketchPath));
87
+ export function resolveSourceMapForProgram(programPath, originalSourceMapPath) {
88
+ const programDir = path.dirname(programPath);
89
+ const programName = path.basename(programPath, path.extname(programPath));
96
90
  // First try the original source map path
97
91
  if (originalSourceMapPath && fs.existsSync(originalSourceMapPath)) {
98
92
  return originalSourceMapPath;
99
93
  }
100
- // Try to find source maps for the sketch directory
94
+ // Try to find source maps for the program directory
101
95
  const possibleMaps = [
102
- path.join(sketchDir, `${sketchName}.thcppmap.json`),
103
- path.join(sketchDir, `${sketchName}.ino.thcppmap.json`),
104
- path.join(sketchDir, "example.thcppmap.json"), // Common case for example sketches
96
+ path.join(programDir, `${programName}.thcppmap.json`),
97
+ path.join(programDir, `${programName}.cpp.thcppmap.json`),
98
+ path.join(programDir, "example.thcppmap.json"), // Common case for example programs
105
99
  ];
106
100
  for (const mapPath of possibleMaps) {
107
101
  if (fs.existsSync(mapPath)) {
108
102
  return mapPath;
109
103
  }
110
104
  }
111
- // Look for any .thcppmap.json files in the sketch directory
105
+ // Look for any .thcppmap.json files in the program directory
112
106
  try {
113
- const files = fs.readdirSync(sketchDir);
107
+ const files = fs.readdirSync(programDir);
114
108
  const mapFiles = files.filter(f => f.endsWith('.thcppmap.json'));
115
109
  if (mapFiles.length > 0) {
116
110
  // Return the most recent one
117
111
  const latest = mapFiles.sort().pop();
118
- return path.join(sketchDir, latest);
112
+ return path.join(programDir, latest);
119
113
  }
120
114
  }
121
115
  catch {
@@ -12,10 +12,10 @@ export declare function topologicalSortFiles(files: string[], dependencies: Map<
12
12
  * Also detects native C++ modules (.d.ts + .cpp pairs).
13
13
  * Files are returned in dependency order (dependencies before dependents).
14
14
  *
15
- * @param boardPackage When provided, `@typecad/board` imports resolve to this
16
- * board package (e.g. `'@typecad/board-arduino-uno'`).
15
+ * @param boardTarget When provided, `@typecad/board` imports fall back to
16
+ * this package specifier (legacy; generated boards win).
17
17
  */
18
- export declare function collectTranspileGraph(entryFile: string, boardPackage?: string, imageDecodeOpts?: {
18
+ export declare function collectTranspileGraph(entryFile: string, boardTarget?: string, imageDecodeOpts?: {
19
19
  maxW?: number;
20
20
  maxH?: number;
21
21
  }): Promise<TranspileGraphResult>;
@@ -3,6 +3,7 @@ import ts from "typescript";
3
3
  import { readText } from "../utils/fs.js";
4
4
  import { detectNativeCppModule, getNpmPackageInfoForFile, isInNodeModules, resolveImport, isCuttlefishSDKPath, } from "../transpile/resolution.js";
5
5
  import { requireUIHook } from "../ui-hook.js";
6
+ import { isSafetyImportSpecifier } from "../safety/specifiers.js";
6
7
  import { registerCuttlefishLibraryFromSpecifier } from "../library-packages.js";
7
8
  /**
8
9
  * Sort files in dependency order using Kahn's algorithm.
@@ -66,10 +67,10 @@ export function topologicalSortFiles(files, dependencies) {
66
67
  * Also detects native C++ modules (.d.ts + .cpp pairs).
67
68
  * Files are returned in dependency order (dependencies before dependents).
68
69
  *
69
- * @param boardPackage When provided, `@typecad/board` imports resolve to this
70
- * board package (e.g. `'@typecad/board-arduino-uno'`).
70
+ * @param boardTarget When provided, `@typecad/board` imports fall back to
71
+ * this package specifier (legacy; generated boards win).
71
72
  */
72
- export async function collectTranspileGraph(entryFile, boardPackage, imageDecodeOpts) {
73
+ export async function collectTranspileGraph(entryFile, boardTarget, imageDecodeOpts) {
73
74
  const ordered = [];
74
75
  const pending = [path.resolve(entryFile)];
75
76
  const visited = new Set();
@@ -134,11 +135,11 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
134
135
  // @typecad/* specifiers, unlike the selective main-loop skip list).
135
136
  if (registerCuttlefishLibraryFromSpecifier(filePath, moduleSpecifier))
136
137
  continue;
137
- if (moduleSpecifier === "@typecad/expect" || moduleSpecifier === "@typecad/ui" || moduleSpecifier === "@typecad/safety")
138
+ if (moduleSpecifier === "@typecad/expect" || moduleSpecifier === "@typecad/ui" || isSafetyImportSpecifier(moduleSpecifier))
138
139
  continue;
139
140
  if (moduleSpecifier.startsWith("@typecad/"))
140
141
  continue;
141
- const resolved = resolveImport(filePath, moduleSpecifier, boardPackage);
142
+ const resolved = resolveImport(filePath, moduleSpecifier, boardTarget);
142
143
  if (!resolved)
143
144
  continue;
144
145
  if (resolved.uiModule)
@@ -179,16 +180,16 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
179
180
  if (moduleSpecifier === "@typecad/expect") {
180
181
  continue;
181
182
  }
182
- // Skip @typecad/ui and @typecad/safety — they provide compile-time
183
- // authoring stubs only. Their calls (ui.mount/signal/bind, safe.read)
184
- // are intercepted at IR-build time and lowered to IR; the packages
185
- // themselves must NOT be emitted as C++ modules (they would synthesize
183
+ // Skip @typecad/ui and the safety authoring surface — they provide
184
+ // compile-time authoring stubs only. Their calls (ui.mount/signal/bind,
185
+ // safe.read) are intercepted at IR-build time and lowered to IR; the
186
+ // modules themselves must NOT be emitted as C++ (they would synthesize
186
187
  // bogus _ui_t / _safe_t structs). All runtime definitions the user code
187
188
  // needs (enums, structs, shims) are provided by the safety polyfill.
188
- if (moduleSpecifier === "@typecad/ui" || moduleSpecifier === "@typecad/safety") {
189
+ if (moduleSpecifier === "@typecad/ui" || isSafetyImportSpecifier(moduleSpecifier)) {
189
190
  continue;
190
191
  }
191
- // Skip @typecad/board, @typecad/board-*, @typecad/mcu-*, @typecad/hal,
192
+ // Skip @typecad/board (virtual), the legacy board/mcu package prefixes, @typecad/hal,
192
193
  // and @typecad/framework-* — these packages ship src/ for HAL metadata
193
194
  // introspection (hal-parser.ts, board-resolver.ts) but their source
194
195
  // must NOT be transpiled to C++. The HAL resolver loads class/method
@@ -205,7 +206,7 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
205
206
  || moduleSpecifier.startsWith("@typecad/framework-")) {
206
207
  continue;
207
208
  }
208
- const resolved = resolveImport(filePath, moduleSpecifier, boardPackage);
209
+ const resolved = resolveImport(filePath, moduleSpecifier, boardTarget);
209
210
  // .ui.html modules: load into the UI registry, record the path, and don't
210
211
  // push onto `pending` (they are never parsed as TypeScript).
211
212
  if (resolved?.uiModule) {