@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
@@ -0,0 +1,14 @@
1
+ // Import specifiers that activate the safety engine. The safety engine was
2
+ // merged into @typecad/cuttlefish from the former @typecad/safety package;
3
+ // both specifiers keep working. Detection is purely by name — the module is
4
+ // never resolved or parsed (the graph builder skips it), so the legacy
5
+ // specifier does not require the frozen npm package to be installed.
6
+ /** The canonical specifier for the safety authoring surface. */
7
+ export const SAFETY_SPECIFIER = "@typecad/cuttlefish/safety";
8
+ /** The legacy specifier from when safety was a standalone package. */
9
+ export const LEGACY_SAFETY_SPECIFIER = "@typecad/safety";
10
+ /** True iff an import specifier refers to the safety authoring surface. */
11
+ export function isSafetyImportSpecifier(moduleSpecifier) {
12
+ return (moduleSpecifier === SAFETY_SPECIFIER ||
13
+ moduleSpecifier === LEGACY_SAFETY_SPECIFIER);
14
+ }
@@ -1,8 +1,9 @@
1
1
  import type { HALOpIR, ProgramIR, RuntimePolyfillIR, Diagnostic } from "./api/shared/index.js";
2
2
  /** Context handed to transformIR. */
3
3
  export interface SafetyTransformContext {
4
- /** True iff the entry file imports `safe` from @typecad/safety. The pass
5
- * uses this as a fast no-op guard. */
4
+ /** True iff the entry file imports `safe` from the safety authoring
5
+ * surface (@typecad/cuttlefish/safety, or legacy @typecad/safety). The
6
+ * pass uses this as a fast no-op guard. */
6
7
  readonly safetyInUse: boolean;
7
8
  /** Build target (e.g. "esp32", "avr"). Strategies still resolve the
8
9
  * underlying pinMode/digitalRead symbols; the safety package is target-
@@ -30,7 +31,7 @@ export interface TranspilerSafetyHook {
30
31
  } | undefined;
31
32
  /** Lower a safe.* TS call to a HAL op. Called from an extension point in
32
33
  * tryResolveSemanticCall (hal-plugins.ts) when the callee resolves to the
33
- * @typecad/safety package. Returns undefined if not a safety call. */
34
+ * safety authoring surface. Returns undefined if not a safety call. */
34
35
  resolveSemanticCall?(callee: string, args: readonly unknown[]): HALOpIR | undefined;
35
36
  /** Provide safety runtime polyfills (mode table + voter). Called from
36
37
  * buildEmitterContext so the polyfills participate in tree-shaking.
@@ -48,12 +49,12 @@ export interface TranspilerSafetyHook {
48
49
  * that the caller writes to a sidecar JSON file. */
49
50
  collectSafetyMetadata?(program: ProgramIR, ctx: SafetyTransformContext): SafetyMetadata[];
50
51
  }
51
- /** Set the safety hook. Called by transpile.ts after dynamically loading
52
- * @typecad/safety/engine. Passing null clears it. */
52
+ /** Set the safety hook. Called by transpile.ts after loading the safety
53
+ * engine. Passing null clears it. */
53
54
  export declare function setSafetyHook(hook: TranspilerSafetyHook | null): void;
54
- /** Get the current safety hook, or null if @typecad/safety is not loaded. */
55
+ /** Get the current safety hook, or null if the safety engine is not loaded. */
55
56
  export declare function getSafetyHook(): TranspilerSafetyHook | null;
56
- /** Returns true if the safety hook is registered (i.e. @typecad/safety loaded). */
57
+ /** Returns true if the safety hook is registered (i.e. safety engine loaded). */
57
58
  export declare function hasSafetyHook(): boolean;
58
59
  /** Get the safety hook, throwing if it's not set. Use only inside
59
60
  * `if (hasSafetyHook())` guards. */
@@ -1,25 +1,24 @@
1
1
  // ---------------------------------------------------------------------------
2
- // Safety hook — the contract cuttlefish core uses to talk to the optional
3
- // @typecad/safety package. Modeled on ui-hook.ts.
2
+ // Safety hook — the contract cuttlefish core uses to talk to the safety
3
+ // engine. Modeled on ui-hook.ts.
4
4
  //
5
- // @typecad/safety is an optional peer dependency. When it is installed and
6
- // imported by a sketch, transpile.ts calls loadSafetyEngine() which dynamic-
7
- // imports @typecad/safety/engine and calls registerSafetyEngine() to push an
8
- // implementation of this interface into the registry. When absent, every
9
- // hasSafetyHook() guard returns false and cuttlefish behaves as before.
5
+ // The engine lives in this package (src/safety/engine.ts); transpile.ts calls
6
+ // loadSafetyEngine() at the start of each run, which registers an
7
+ // implementation of this interface. The seam is kept so the degradation paths
8
+ // (resetSafetyEngine / __simulateSafetyAbsentForTest) stay testable.
10
9
  // ---------------------------------------------------------------------------
11
10
  // ── Module-level hook state ────────────────────────────────────────────────
12
11
  let safetyHook = null;
13
- /** Set the safety hook. Called by transpile.ts after dynamically loading
14
- * @typecad/safety/engine. Passing null clears it. */
12
+ /** Set the safety hook. Called by transpile.ts after loading the safety
13
+ * engine. Passing null clears it. */
15
14
  export function setSafetyHook(hook) {
16
15
  safetyHook = hook;
17
16
  }
18
- /** Get the current safety hook, or null if @typecad/safety is not loaded. */
17
+ /** Get the current safety hook, or null if the safety engine is not loaded. */
19
18
  export function getSafetyHook() {
20
19
  return safetyHook;
21
20
  }
22
- /** Returns true if the safety hook is registered (i.e. @typecad/safety loaded). */
21
+ /** Returns true if the safety hook is registered (i.e. safety engine loaded). */
23
22
  export function hasSafetyHook() {
24
23
  return safetyHook !== null;
25
24
  }
@@ -27,8 +26,8 @@ export function hasSafetyHook() {
27
26
  * `if (hasSafetyHook())` guards. */
28
27
  export function requireSafetyHook() {
29
28
  if (!safetyHook) {
30
- throw new Error("Safety hook is not registered. This code path requires @typecad/safety " +
31
- "to be installed and loaded. This should not happen — the hook is set " +
29
+ throw new Error("Safety hook is not registered. This code path requires the safety " +
30
+ "engine to be loaded. This should not happen — the hook is set " +
32
31
  "at the start of transpileFile() when safety is detected.");
33
32
  }
34
33
  return safetyHook;
package/dist/testing.d.ts CHANGED
@@ -19,11 +19,8 @@ export { transpileFile } from "./transpile.js";
19
19
  export { resetUIEngine, __simulateUIAbsentForTest } from "./ui/ui-bridge.js";
20
20
  export { resetSafetyEngine, __simulateSafetyAbsentForTest } from "./safety/safety-bridge.js";
21
21
  export { setSafetyHook, hasSafetyHook } from "./safety-hook.js";
22
- export { scaffoldProject, normalizeProjectName, KNOWN_BOARDS, generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, runInitWizard, } from "./create/index.js";
23
- export type { InitProjectOptions } from "./create/index.js";
24
- export { scaffoldBoardPackages, parseBoardSpec, safeParseBoardSpec, stripJsonc, } from "./create/index.js";
25
- export type { BoardSpec, ScaffoldBoardResult } from "./create/index.js";
26
- export { BoardGenerators } from "./create/index.js";
22
+ export { scaffoldProject, normalizeProjectName, generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterProgram, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, runCreateWizard, } from "./create/index.js";
23
+ export type { CreateProjectOptions } from "./create/index.js";
27
24
  export { buildCallGraph, getReachableSymbols } from "./ir/call-graph.js";
28
25
  export { detectEntryPoints, detectExportedEntryPoints } from "./ir/entry-points.js";
29
26
  export { analyzeReachability, getReachabilityStats } from "./ir/reachability.js";
@@ -37,6 +34,8 @@ export type { ESLintError } from "./eslint-check.js";
37
34
  export { checkLintCache, recordLintSuccess, invalidateLint, computeLintFingerprint, resolveEslintConfigPath, } from "./lint-cache.js";
38
35
  export type { LintFingerprint, GateCacheResult } from "./lint-cache.js";
39
36
  export { runSemanticGates } from "./orchestrator/type-checker.js";
37
+ export { readGeneratedBoardConstants } from "./ir/board-resolver.js";
38
+ export { pinEntryIndexForNumber } from "./ir/pin-capability-validation.js";
40
39
  export { canonicalize, buildSemanticFacts, } from "./orchestrator/semantic-facts.js";
41
40
  export type { CanonicalType, SemanticFacts, FactStore, ValueCategory, Lifetime, Nullable, SemanticOrigin, AnalysisResult, BindingResolver, } from "./orchestrator/semantic-facts.js";
42
41
  export { verifyFacts } from "./orchestrator/semantic-facts-verifier.js";
@@ -46,7 +45,7 @@ export { parseCommandLine } from "./utils/cli.js";
46
45
  export { parseHeader, stripPreprocessorBlocks } from "./libdef/header-parser.js";
47
46
  export { BaseClassResolver, buildClassIndex } from "./libdef/base-class-resolver.js";
48
47
  export type { ResolveResult } from "./libdef/base-class-resolver.js";
49
- export { generateDecl, generateDeclsForDirectory, generateComponentDeclsForProject } from "./libdef/cpp-to-decl.js";
48
+ export { generateDecl, generateDeclsForDirectory } from "./libdef/cpp-to-decl.js";
50
49
  export { renderExprAsText } from "./ir/render-expr.js";
51
50
  export { contextStorage, CompilationContext } from "./ir/build-ir-state.js";
52
51
  export type { ExpressionIR } from "./api/index.js";
package/dist/testing.js CHANGED
@@ -23,10 +23,7 @@ export { resetUIEngine, __simulateUIAbsentForTest } from "./ui/ui-bridge.js";
23
23
  export { resetSafetyEngine, __simulateSafetyAbsentForTest } from "./safety/safety-bridge.js";
24
24
  export { setSafetyHook, hasSafetyHook } from "./safety-hook.js";
25
25
  // ── Project scaffolding ──────────────────────────────────────────────────────
26
- export { scaffoldProject, normalizeProjectName, KNOWN_BOARDS, generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, runInitWizard, } from "./create/index.js";
27
- // ── Board codegen (`cuttlefish board add`) ───────────────────────────────────
28
- export { scaffoldBoardPackages, parseBoardSpec, safeParseBoardSpec, stripJsonc, } from "./create/index.js";
29
- export { BoardGenerators } from "./create/index.js";
26
+ export { scaffoldProject, normalizeProjectName, generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterProgram, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, runCreateWizard, } from "./create/index.js";
30
27
  // ── Tree-shaking & reachability ──────────────────────────────────────────────
31
28
  export { buildCallGraph, getReachableSymbols } from "./ir/call-graph.js";
32
29
  export { detectEntryPoints, detectExportedEntryPoints } from "./ir/entry-points.js";
@@ -43,6 +40,9 @@ export { runEslintCheck } from "./eslint-check.js";
43
40
  export { checkLintCache, recordLintSuccess, invalidateLint, computeLintFingerprint, resolveEslintConfigPath, } from "./lint-cache.js";
44
41
  // ── Semantic gates (TypeChecker-based) ──────────────────────────────────────
45
42
  export { runSemanticGates } from "./orchestrator/type-checker.js";
43
+ // ── Board constants / pin capability internals ──────────────────────────────
44
+ export { readGeneratedBoardConstants } from "./ir/board-resolver.js";
45
+ export { pinEntryIndexForNumber } from "./ir/pin-capability-validation.js";
46
46
  export { canonicalize, buildSemanticFacts, } from "./orchestrator/semantic-facts.js";
47
47
  export { verifyFacts } from "./orchestrator/semantic-facts-verifier.js";
48
48
  // ── Watch & CLI utilities ───────────────────────────────────────────────────
@@ -50,7 +50,7 @@ export { discoverWatchDirs, isRelevantChange } from "./watch.js";
50
50
  export { parseCommandLine } from "./utils/cli.js";
51
51
  export { parseHeader, stripPreprocessorBlocks } from "./libdef/header-parser.js";
52
52
  export { BaseClassResolver, buildClassIndex } from "./libdef/base-class-resolver.js";
53
- export { generateDecl, generateDeclsForDirectory, generateComponentDeclsForProject } from "./libdef/cpp-to-decl.js";
53
+ export { generateDecl, generateDeclsForDirectory } from "./libdef/cpp-to-decl.js";
54
54
  // ── IR rendering internals (for fail-closed regression tests) ───────────────
55
55
  export { renderExprAsText } from "./ir/render-expr.js";
56
56
  export { contextStorage, CompilationContext } from "./ir/build-ir-state.js";
@@ -18,7 +18,7 @@ export interface TranspileGraphResult {
18
18
  /** `.ui.html` modules discovered during graph build, keyed by resolved path. */
19
19
  uiModules: Set<string>;
20
20
  }
21
- export declare function resolveImport(fromFile: string, moduleSpecifier: string, boardPackage?: string): {
21
+ export declare function resolveImport(fromFile: string, moduleSpecifier: string, boardTarget?: string): {
22
22
  sourcePath: string;
23
23
  npmPackage?: ResolvedNpmPackage;
24
24
  uiModule?: boolean;
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { findGeneratedBoard } from "../ir/board-resolver.js";
3
4
  function resolveLocalImport(fromFile, moduleSpecifier) {
4
5
  if (!moduleSpecifier.startsWith(".")) {
5
6
  return undefined;
@@ -179,13 +180,19 @@ function resolveNpmPackageImport(fromFile, moduleSpecifier) {
179
180
  moduleKey,
180
181
  };
181
182
  }
182
- export function resolveImport(fromFile, moduleSpecifier, boardPackage) {
183
+ export function resolveImport(fromFile, moduleSpecifier, boardTarget) {
183
184
  let effectiveSpecifier = moduleSpecifier;
184
- // The `@typecad/board` virtual import resolves to the configured board package.
185
- // (Case-insensitive so the documented mixed-case form is treated identically.)
186
- if (moduleSpecifier.toLowerCase() === "@typecad/board" && boardPackage) {
187
- effectiveSpecifier = boardPackage;
185
+ // The `@typecad/board` virtual import resolves to the project-local
186
+ // generated board module (.cuttlefish/board.ts) when one exists the
187
+ // config's board target materialized by boardgen. Falls through to the
188
+ // package-based path otherwise (transition; board packages are going away).
189
+ if (moduleSpecifier.toLowerCase() === "@typecad/board") {
190
+ const generated = findGeneratedBoard(fromFile);
191
+ if (generated) {
192
+ return { sourcePath: generated.boardTs };
193
+ }
188
194
  }
195
+ void boardTarget;
189
196
  const localResolved = resolveLocalImport(fromFile, effectiveSpecifier);
190
197
  if (localResolved) {
191
198
  // .ui.html files resolve as UI modules, not TypeScript sources. Only set
@@ -271,12 +278,14 @@ export function detectNativeCppModule(fromFile, moduleSpecifier) {
271
278
  export function isCuttlefishSDKPath(filePath) {
272
279
  const normalized = filePath.replace(/\\/g, "/");
273
280
  return (/\/code\/core\//.test(normalized) ||
274
- /\/code\/board-/.test(normalized) ||
275
- /\/packages\/board-/.test(normalized) ||
276
281
  /\/packages\/expect\//.test(normalized) ||
277
282
  /\/packages\/cuttlefish\//.test(normalized) ||
278
- /\/node_modules\/@typecad\/board-/.test(normalized) ||
279
283
  /\/node_modules\/@typecad\/core\//.test(normalized) ||
280
284
  /\/node_modules\/@typecad\/expect\//.test(normalized) ||
281
- /\/node_modules\/@typecad\/cuttlefish\//.test(normalized));
285
+ /\/node_modules\/@typecad\/cuttlefish\//.test(normalized) ||
286
+ // The generated project-local board module: like @typecad/hal, its source
287
+ // exists for pin resolution (halInstances / board constants), never for
288
+ // C++ emission — transpiling it would treat LED/PA5 as cross-module
289
+ // imports instead of compile-time pin facts.
290
+ /\/\.cuttlefish\/board\.ts$/.test(normalized));
282
291
  }
@@ -0,0 +1,18 @@
1
+ export interface TestPinsFile {
2
+ pins?: Record<string, string | string[]>;
3
+ facts?: Record<string, number>;
4
+ }
5
+ /** Read and parse a project's test-pins.json. Returns undefined when absent. */
6
+ export declare function readTestPinsFile(projectDir: string): TestPinsFile | undefined;
7
+ /**
8
+ * Build the generated module's source: role consts re-exported from the
9
+ * board package. Used by the editor-support generator
10
+ * (.cuttlefish/test-pins.ts — see config-loader's generateVirtualTypeDeclaration)
11
+ * so the language server resolves the '@typecad/test-pins' specifier.
12
+ * Hardware runs do NOT transpile this module: the @typecad/expect
13
+ * preprocessor substitutes role identifiers in test sources with the
14
+ * board's real pin symbols before the transpiler runs (the HAL resolves
15
+ * pins through board-package metadata, not through transpiled modules).
16
+ * Returns undefined when the board declares no usable roles.
17
+ */
18
+ export declare function buildTestPinsModuleContent(boardTarget: string, data: TestPinsFile): string | undefined;
@@ -0,0 +1,142 @@
1
+ // ---------------------------------------------------------------------------
2
+ // @typecad/test-pins — board test-pin role data
3
+ //
4
+ // Boards describe their testable pins declaratively in a `test-pins.json`
5
+ // shipped next to their package.json. Test suites import stable role names
6
+ // from the '@typecad/test-pins' virtual module:
7
+ //
8
+ // import { GPIO_OUT, PWM_PIN } from '@typecad/test-pins';
9
+ //
10
+ // At hardware-test time the @typecad/expect preprocessor substitutes each
11
+ // role identifier in the test source with the board's real pin symbol (and
12
+ // each fact with its numeric literal), rewriting the import to
13
+ // '@typecad/board' — the exact lowering path hand-written per-board tests
14
+ // use. This module provides the schema, the JSON reader, and the
15
+ // editor-support generator (config-loader writes .cuttlefish/test-pins.ts
16
+ // so the language server resolves the specifier).
17
+ //
18
+ // Schema (all fields optional — a board only declares what it can test;
19
+ // suites gate themselves on role availability via `@typecad-requires-roles`):
20
+ //
21
+ // {
22
+ // "pins": {
23
+ // "gpioOut": "PB5", -> GPIO_OUT
24
+ // "gpioIn": "PB0", -> GPIO_IN
25
+ // "pwm": "PB6", -> PWM_PIN
26
+ // "pwmAlt": "PB7", -> PWM_ALT
27
+ // "cs": "PA4", -> CS_PIN
28
+ // "interrupt": "PA0", -> INT_PIN
29
+ // "led": "PC13", -> LED_PIN
30
+ // "button": "PA0" -> BUTTON_PIN
31
+ // },
32
+ // "facts": {
33
+ // "adcMax": 4095 -> ADC_MAX
34
+ // },
35
+ // "usb": { -> port discovery (host side only):
36
+ // "vid": "2FE3", multi-board test rigs match the
37
+ // "pid": "0001", console/upload port by USB identity
38
+ // "serial": "…" (optional) instead of tracking COM/tty numbers;
39
+ // } Zephyr CDC boards all enumerate at
40
+ // } the default 2FE3:0001 — run one CDC
41
+ // board at a time (see the expect
42
+ // README's "USB port discovery")
43
+ // }
44
+ // ---------------------------------------------------------------------------
45
+ import fs from "node:fs";
46
+ import path from "node:path";
47
+ /** Pin role -> exported const name. Single source for generator + env typing. */
48
+ const PIN_ROLES = {
49
+ gpioOut: "GPIO_OUT",
50
+ gpioIn: "GPIO_IN",
51
+ pwm: "PWM_PIN",
52
+ pwmAlt: "PWM_ALT",
53
+ adcPin: "ADC_PIN",
54
+ adcPinAlt: "ADC_PIN_ALT",
55
+ cs: "CS_PIN",
56
+ interrupt: "INT_PIN",
57
+ led: "LED_PIN",
58
+ button: "BUTTON_PIN",
59
+ // Bus selector roles carry a quoted instance name ('I2C0'), not a pin
60
+ // symbol — they export as string literals and substitute inline the same
61
+ // way (the value text already includes the quotes).
62
+ i2cBus: "I2C_BUS",
63
+ };
64
+ /** Fact role -> exported const name. */
65
+ const FACT_ROLES = {
66
+ adcMax: "ADC_MAX",
67
+ };
68
+ const IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
69
+ /** Read and parse a project's test-pins.json. Returns undefined when absent. */
70
+ export function readTestPinsFile(projectDir) {
71
+ const jsonPath = path.join(projectDir, "test-pins.json");
72
+ if (!fs.existsSync(jsonPath))
73
+ return undefined;
74
+ try {
75
+ return JSON.parse(fs.readFileSync(jsonPath, "utf8"));
76
+ }
77
+ catch (e) {
78
+ console.error(`[test-pins] Failed to parse ${jsonPath}: ${e.message}`);
79
+ return undefined;
80
+ }
81
+ }
82
+ /**
83
+ * Build the generated module's source: role consts re-exported from the
84
+ * board package. Used by the editor-support generator
85
+ * (.cuttlefish/test-pins.ts — see config-loader's generateVirtualTypeDeclaration)
86
+ * so the language server resolves the '@typecad/test-pins' specifier.
87
+ * Hardware runs do NOT transpile this module: the @typecad/expect
88
+ * preprocessor substitutes role identifiers in test sources with the
89
+ * board's real pin symbols before the transpiler runs (the HAL resolves
90
+ * pins through board-package metadata, not through transpiled modules).
91
+ * Returns undefined when the board declares no usable roles.
92
+ */
93
+ export function buildTestPinsModuleContent(boardTarget, data) {
94
+ const lines = [
95
+ `// Generated from ${boardTarget}/test-pins.json by the '@typecad/test-pins'`,
96
+ `// resolver. Do not edit — regenerated on every transpile.`,
97
+ `import {`,
98
+ ];
99
+ const importedPins = [];
100
+ const exports = [];
101
+ for (const [role, constName] of Object.entries(PIN_ROLES)) {
102
+ const value = data.pins?.[role];
103
+ if (value === undefined)
104
+ continue;
105
+ if (Array.isArray(value)) {
106
+ const names = value.filter((n) => typeof n === "string" && IDENTIFIER_RE.test(n));
107
+ if (names.length === 0)
108
+ continue;
109
+ importedPins.push(...names);
110
+ exports.push(`export const ${constName} = [${names.join(", ")}];`);
111
+ }
112
+ else if (typeof value === "string" && IDENTIFIER_RE.test(value)) {
113
+ importedPins.push(value);
114
+ exports.push(`export const ${constName} = ${value};`);
115
+ }
116
+ else if (typeof value === "string" && /^'[^']*'$/.test(value)) {
117
+ // Quoted selector text (a bus instance name) — export as-is; no board
118
+ // pin import needed.
119
+ exports.push(`export const ${constName} = ${value};`);
120
+ }
121
+ else {
122
+ console.error(`[test-pins] Ignoring invalid pin role '${role}' in test-pins.json`);
123
+ }
124
+ }
125
+ for (const [role, constName] of Object.entries(FACT_ROLES)) {
126
+ const value = data.facts?.[role];
127
+ if (typeof value !== "number" || !Number.isFinite(value))
128
+ continue;
129
+ exports.push(`export const ${constName} = ${value};`);
130
+ }
131
+ if (importedPins.length === 0 && exports.length === 0)
132
+ return undefined;
133
+ for (const name of [...new Set(importedPins)].sort()) {
134
+ lines.push(` ${name},`);
135
+ }
136
+ // Pin symbols live in the generated board module (the .cuttlefish sibling).
137
+ lines.push(`} from './board.js';`);
138
+ lines.push("");
139
+ lines.push(...exports);
140
+ lines.push("");
141
+ return lines.join("\n");
142
+ }
@@ -1,6 +1,5 @@
1
- import { GenerateLibdefOptions, GeneratedOutputs, TranspileOptions } from "./types.js";
1
+ import { GeneratedOutputs, TranspileOptions } from "./types.js";
2
2
  import { loadFrameworkPackage } from "./framework-package.js";
3
3
  export { loadFrameworkPackage };
4
4
  export { getLoadedFramework, hasLoadedFramework } from "./framework-registry.js";
5
5
  export declare function transpileFile(options: TranspileOptions): Promise<GeneratedOutputs>;
6
- export declare function generateLibraryDefinitions(options: GenerateLibdefOptions): string[];