@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
@@ -3,6 +3,8 @@ 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";
7
+ import { registerCuttlefishLibraryFromSpecifier } from "../library-packages.js";
6
8
  /**
7
9
  * Sort files in dependency order using Kahn's algorithm.
8
10
  * Dependencies come before dependents so that include ordering is correct
@@ -65,10 +67,10 @@ export function topologicalSortFiles(files, dependencies) {
65
67
  * Also detects native C++ modules (.d.ts + .cpp pairs).
66
68
  * Files are returned in dependency order (dependencies before dependents).
67
69
  *
68
- * @param boardPackage When provided, `@typecad/board` imports resolve to this
69
- * 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).
70
72
  */
71
- export async function collectTranspileGraph(entryFile, boardPackage, imageDecodeOpts) {
73
+ export async function collectTranspileGraph(entryFile, boardTarget, imageDecodeOpts) {
72
74
  const ordered = [];
73
75
  const pending = [path.resolve(entryFile)];
74
76
  const visited = new Set();
@@ -125,11 +127,19 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
125
127
  }
126
128
  if (!moduleSpecifier)
127
129
  continue;
128
- if (moduleSpecifier === "@typecad/expect" || moduleSpecifier === "@typecad/ui" || moduleSpecifier === "@typecad/safety")
130
+ // Cuttlefish library package: an import whose package ships a
131
+ // cuttlefish.library.json contributes native shims + build fragments
132
+ // instead of transpiling — its own TypeScript types are the contract.
133
+ // Must precede the @typecad/* skips: scoped libraries would otherwise
134
+ // be dropped as "SDK packages" here (the .ui script loop skips ALL
135
+ // @typecad/* specifiers, unlike the selective main-loop skip list).
136
+ if (registerCuttlefishLibraryFromSpecifier(filePath, moduleSpecifier))
137
+ continue;
138
+ if (moduleSpecifier === "@typecad/expect" || moduleSpecifier === "@typecad/ui" || isSafetyImportSpecifier(moduleSpecifier))
129
139
  continue;
130
140
  if (moduleSpecifier.startsWith("@typecad/"))
131
141
  continue;
132
- const resolved = resolveImport(filePath, moduleSpecifier, boardPackage);
142
+ const resolved = resolveImport(filePath, moduleSpecifier, boardTarget);
133
143
  if (!resolved)
134
144
  continue;
135
145
  if (resolved.uiModule)
@@ -158,21 +168,28 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
158
168
  nativeModules.set(moduleSpecifier, nativeModule);
159
169
  continue; // Don't try to resolve as TypeScript
160
170
  }
171
+ // Cuttlefish library package: an import whose package ships a
172
+ // cuttlefish.library.json contributes native shims + build fragments
173
+ // instead of transpiling — its own TypeScript types are the contract.
174
+ // Checked before the @typecad/* skips so scoped libraries register.
175
+ if (registerCuttlefishLibraryFromSpecifier(filePath, moduleSpecifier)) {
176
+ continue;
177
+ }
161
178
  // Skip @typecad/expect — it provides type-level stubs only.
162
179
  // The AST preprocessor rewrites all expect calls before transpilation.
163
180
  if (moduleSpecifier === "@typecad/expect") {
164
181
  continue;
165
182
  }
166
- // Skip @typecad/ui and @typecad/safety — they provide compile-time
167
- // authoring stubs only. Their calls (ui.mount/signal/bind, safe.read)
168
- // are intercepted at IR-build time and lowered to IR; the packages
169
- // 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
170
187
  // bogus _ui_t / _safe_t structs). All runtime definitions the user code
171
188
  // needs (enums, structs, shims) are provided by the safety polyfill.
172
- if (moduleSpecifier === "@typecad/ui" || moduleSpecifier === "@typecad/safety") {
189
+ if (moduleSpecifier === "@typecad/ui" || isSafetyImportSpecifier(moduleSpecifier)) {
173
190
  continue;
174
191
  }
175
- // Skip @typecad/board, @typecad/board-*, @typecad/mcu-*, @typecad/hal,
192
+ // Skip @typecad/board (virtual), the legacy board/mcu package prefixes, @typecad/hal,
176
193
  // and @typecad/framework-* — these packages ship src/ for HAL metadata
177
194
  // introspection (hal-parser.ts, board-resolver.ts) but their source
178
195
  // must NOT be transpiled to C++. The HAL resolver loads class/method
@@ -189,7 +206,7 @@ export async function collectTranspileGraph(entryFile, boardPackage, imageDecode
189
206
  || moduleSpecifier.startsWith("@typecad/framework-")) {
190
207
  continue;
191
208
  }
192
- const resolved = resolveImport(filePath, moduleSpecifier, boardPackage);
209
+ const resolved = resolveImport(filePath, moduleSpecifier, boardTarget);
193
210
  // .ui.html modules: load into the UI registry, record the path, and don't
194
211
  // push onto `pending` (they are never parsed as TypeScript).
195
212
  if (resolved?.uiModule) {
@@ -22,11 +22,11 @@ export interface TypeCheckResult {
22
22
  * Returns early if any errors are found.
23
23
  *
24
24
  * @param files List of TypeScript files to type-check
25
- * @param _boardPackage Optional board package for resolving @typecad/board imports
26
- * @param entryFile Entrypoint sketch/main file
25
+ * @param _boardTarget Optional board package for resolving @typecad/board imports
26
+ * @param entryFile Entrypoint source/main file
27
27
  * @returns TypeCheckResult with success status and any error messages
28
28
  */
29
- export declare function typeCheckFiles(files: string[], _boardPackage?: string, entryFile?: string): TypeCheckResult;
29
+ export declare function typeCheckFiles(files: string[], _boardTarget?: string, entryFile?: string): TypeCheckResult;
30
30
  /**
31
31
  * Run semantic gates against the user files of a type-checked program.
32
32
  *
@@ -10,11 +10,11 @@ import { requireUIHook, hasUIHook } from "../ui-hook.js";
10
10
  * Returns early if any errors are found.
11
11
  *
12
12
  * @param files List of TypeScript files to type-check
13
- * @param _boardPackage Optional board package for resolving @typecad/board imports
14
- * @param entryFile Entrypoint sketch/main file
13
+ * @param _boardTarget Optional board package for resolving @typecad/board imports
14
+ * @param entryFile Entrypoint source/main file
15
15
  * @returns TypeCheckResult with success status and any error messages
16
16
  */
17
- export function typeCheckFiles(files, _boardPackage, entryFile) {
17
+ export function typeCheckFiles(files, _boardTarget, entryFile) {
18
18
  // Find the nearest tsconfig.json by walking up from the entry file (preferred)
19
19
  // or the first file in the graph. Using the entry file ensures we pick up the
20
20
  // user's tsconfig (with path mappings) rather than a dependency's tsconfig.
@@ -16,7 +16,7 @@ export function buildAsyncRuntimePolyfill(program, ctx, target, queueCapacity, s
16
16
  // instead of a millis() token the generic target never defines). When the
17
17
  // expression uses std::chrono, the polyfill must carry <chrono> itself —
18
18
  // the generic strategy's forcedIncludes are empty by design.
19
- const now = strategy?.currentTimeMillis?.() ?? "millis()";
19
+ const now = strategy?.currentTimeMillis?.() ?? "__tc_now_ms()";
20
20
  const requiredIncludes = ["<functional>", "<vector>", "<utility>", "<string>"];
21
21
  if (now.includes("std::chrono"))
22
22
  requiredIncludes.push("<chrono>");
@@ -14,14 +14,14 @@ import { generateCoopScheduler } from "../api/shared/index.js";
14
14
  * links on minimal-libc targets (Zephyr) where the std::function Promise
15
15
  * runtime does not.
16
16
  */
17
- export function buildCoopSchedulerPolyfill(_program, config, currentTimeExpr = "millis()") {
17
+ export function buildCoopSchedulerPolyfill(_program, config, currentTimeExpr = "__tc_now_ms()") {
18
18
  if (!config.enablePriority && !config.enableTimeBudget)
19
19
  return null;
20
20
  return {
21
21
  kind: "polyfill",
22
22
  id: "coop_scheduler",
23
23
  domain: "embedded",
24
- // STL-free: only needs a 32-bit unsigned time source (millis() /
24
+ // STL-free: only needs a 32-bit unsigned time source (__tc_now_ms() /
25
25
  // k_uptime_get_32()) and fixed-width types, both available everywhere.
26
26
  requiredIncludes: [],
27
27
  forwardDeclarations: [],
@@ -0,0 +1,36 @@
1
+ export interface CapturedVariable {
2
+ name: string;
3
+ isFunction?: boolean;
4
+ /** Coarse C++ type category (inferred by the preprocessor without a checker). */
5
+ cppType?: 'bool' | 'int' | 'long' | 'float' | 'string' | 'unknown';
6
+ }
7
+ export interface LogMessagePart {
8
+ type: 'text' | 'variable';
9
+ value: string;
10
+ }
11
+ /**
12
+ * Generate the debug-mode banner. The host console needs no setup, but the
13
+ * printf/getchar calls below need <cstdio>: include() registers it on the
14
+ * program (the generic strategy's forcedIncludes is deliberately empty), and
15
+ * the strategy-side usesCstdio gates (e.g. native) also pick the banner up
16
+ * from the rawCpp text.
17
+ */
18
+ export declare function generateGenericInitCode(): string[];
19
+ /**
20
+ * Generate generic/native code for a breakpoint.
21
+ *
22
+ * The halt reads stdin until ENTER; any 's' typed before it marks this
23
+ * breakpoint skipped for the rest of the run. The flag is a C++ static local
24
+ * inside the emitted block (safe here — unlike TS-injected declarations, the
25
+ * rawCpp text bypasses the TS parser entirely), so the skip persists across
26
+ * loop() iterations. EOF on stdin exits the halt instead of spinning.
27
+ *
28
+ * When `breakpointId` is set the whole block is guarded by that flag; the
29
+ * preprocessor assigns ids to every halting breakpoint.
30
+ */
31
+ export declare function generateGenericBreakpointCode(fileName: string, lineNum: number, originalLine: string, variables: CapturedVariable[], normalizedCondition: string | undefined, breakpointId?: number): string[];
32
+ /**
33
+ * Generate generic/native code for a logpoint (logs a message without
34
+ * halting). Each part is its own printf, then a newline.
35
+ */
36
+ export declare function generateGenericLogpointCode(fileName: string, lineNum: number, parts: LogMessagePart[], variables: CapturedVariable[]): string[];
@@ -0,0 +1,185 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Generic/native debug code generator — printf-based debug output
3
+ //
4
+ // The debug preprocessor injects these lines into the user's TypeScript, so
5
+ // every injected line must be TS-parseable AND lower faithfully. Raw C++ in
6
+ // an injected line does not survive: the TS parser reads `std::cout << ...`
7
+ // as a label plus garbage, and the emitted C++ was `std: :` noise that could
8
+ // never compile. Every line therefore rides the rawCpp() passthrough — the
9
+ // call lowers to __EMIT__ and its string argument is emitted as verbatim
10
+ // C++ — so the generator can author arbitrary C++ (printf, static_cast,
11
+ // the static skip flag) without the TS parser ever seeing it.
12
+ //
13
+ // printf/getchar need <cstdio>: program-analysis marks usesCstdio from
14
+ // __EMIT__ string arguments, and the native/generic forcedIncludes gate
15
+ // <cstdio> on that flag.
16
+ //
17
+ // Used by GenericStrategy's generateDebug* overrides (the debug preprocessor
18
+ // falls back to GenericStrategy for every framework whose strategy does not
19
+ // define its own codegen — e.g. @typecad/framework-native). The Zephyr
20
+ // counterpart is framework-zephyr/src/debug-codegen.ts (printk + a shim-side
21
+ // halt). Dispatched by cuttlefish/src/debug/preprocessor.ts.
22
+ // ---------------------------------------------------------------------------
23
+ import { escapeCppStringLiteral } from "../utils/strings.js";
24
+ /**
25
+ * Wrap a C++ text fragment as an injectable TS statement. The rawCpp() call
26
+ * lowers to __EMIT__, whose string argument the emitter writes out verbatim
27
+ * (a trailing `;` is added by the emitter when the fragment lacks one).
28
+ * JSON.stringify produces a valid single-line TS double-quoted literal for
29
+ * any fragment, newlines included.
30
+ */
31
+ function raw(cpp) {
32
+ return `rawCpp(${JSON.stringify(cpp)});`;
33
+ }
34
+ /** printf a string literal. */
35
+ function printLiteral(text, indent) {
36
+ return raw(`${indent}printf("%s", "${escapeCppStringLiteral(text)}");`);
37
+ }
38
+ /**
39
+ * Generate the debug-mode banner. The host console needs no setup, but the
40
+ * printf/getchar calls below need <cstdio>: include() registers it on the
41
+ * program (the generic strategy's forcedIncludes is deliberately empty), and
42
+ * the strategy-side usesCstdio gates (e.g. native) also pick the banner up
43
+ * from the rawCpp text.
44
+ */
45
+ export function generateGenericInitCode() {
46
+ return [
47
+ '// === DEBUG: host console (printf) ===',
48
+ "include('<cstdio>');",
49
+ raw('printf("[TypeCAD] Debug Mode Active\\n");'),
50
+ '// === END DEBUG INIT ===',
51
+ '',
52
+ ];
53
+ }
54
+ /**
55
+ * Generate generic/native code for a breakpoint.
56
+ *
57
+ * The halt reads stdin until ENTER; any 's' typed before it marks this
58
+ * breakpoint skipped for the rest of the run. The flag is a C++ static local
59
+ * inside the emitted block (safe here — unlike TS-injected declarations, the
60
+ * rawCpp text bypasses the TS parser entirely), so the skip persists across
61
+ * loop() iterations. EOF on stdin exits the halt instead of spinning.
62
+ *
63
+ * When `breakpointId` is set the whole block is guarded by that flag; the
64
+ * preprocessor assigns ids to every halting breakpoint.
65
+ */
66
+ export function generateGenericBreakpointCode(fileName, lineNum, originalLine, variables, normalizedCondition, breakpointId) {
67
+ const lines = [];
68
+ const indent = ' ' + (normalizedCondition ? ' ' : '');
69
+ lines.push(` // === BREAKPOINT: ${fileName}:${lineNum} ===`);
70
+ if (normalizedCondition) {
71
+ lines.push(` if (${normalizedCondition}) {`);
72
+ }
73
+ // The whole breakpoint is one rawCpp block: a braced C++ compound
74
+ // statement. The emitter only appends a `;` when the fragment lacks one,
75
+ // so a block ending in `}` is written out verbatim.
76
+ const flag = breakpointId !== undefined ? `__tc_bp${breakpointId}_skipped` : undefined;
77
+ const b = ['{'];
78
+ const inner = flag ? ' ' : '';
79
+ if (flag) {
80
+ b.push(` static bool ${flag} = false;`);
81
+ b.push(` if (!${flag}) {`);
82
+ }
83
+ b.push(`${inner}printf("----------------------------------------\\n");`);
84
+ const headerText = normalizedCondition
85
+ ? `[BREAK] ${fileName}:${lineNum} (condition: ${escapeCppStringLiteral(normalizedCondition)})`
86
+ : `[BREAK] ${fileName}:${lineNum}`;
87
+ b.push(`${inner}printf("%s\\n", "${escapeCppStringLiteral(headerText)}");`);
88
+ b.push(`${inner}printf(" %s\\n", "${escapeCppStringLiteral(originalLine)}");`);
89
+ if (variables.length > 0) {
90
+ b.push(`${inner}printf(" Variables:\\n");`);
91
+ for (const v of variables) {
92
+ if (v.isFunction) {
93
+ b.push(`${inner}printf(" - %s = [function]\\n", "${escapeCppStringLiteral(v.name)}");`);
94
+ }
95
+ else {
96
+ const { spec, arg } = formatSpecFor(v.name, v.cppType);
97
+ b.push(`${inner}printf(" - %s = ${spec}\\n", "${escapeCppStringLiteral(v.name)}", ${arg});`);
98
+ }
99
+ }
100
+ }
101
+ else {
102
+ b.push(`${inner}printf(" (no variables in scope)\\n");`);
103
+ }
104
+ b.push(`${inner}printf(" [ENTER: continue | s: skip this breakpoint]\\n");`);
105
+ b.push(`${inner}int __tc_c;`);
106
+ if (flag) {
107
+ b.push(`${inner}do {`);
108
+ b.push(`${inner} __tc_c = getchar();`);
109
+ b.push(`${inner} if (__tc_c == 's') { ${flag} = true; }`);
110
+ b.push(`${inner}} while (__tc_c != '\\n' && __tc_c != EOF);`);
111
+ }
112
+ else {
113
+ b.push(`${inner}do {`);
114
+ b.push(`${inner} __tc_c = getchar();`);
115
+ b.push(`${inner}} while (__tc_c != '\\n' && __tc_c != EOF);`);
116
+ }
117
+ if (flag) {
118
+ b.push(' }');
119
+ }
120
+ b.push('}');
121
+ lines.push(indent + raw(b.join('\n')));
122
+ if (normalizedCondition) {
123
+ lines.push(` }`);
124
+ }
125
+ lines.push(` // === END BREAKPOINT ===`);
126
+ return lines;
127
+ }
128
+ /**
129
+ * Generate generic/native code for a logpoint (logs a message without
130
+ * halting). Each part is its own printf, then a newline.
131
+ */
132
+ export function generateGenericLogpointCode(fileName, lineNum, parts, variables) {
133
+ const lines = [];
134
+ lines.push(` // === LOGPOINT: ${fileName}:${lineNum} ===`);
135
+ lines.push(raw(` printf("%s", "${escapeCppStringLiteral(`[LOG ${fileName}:${lineNum}] `)}");`));
136
+ for (const part of parts) {
137
+ if (part.type === 'text') {
138
+ lines.push(raw(` printf("%s", "${escapeCppStringLiteral(part.value)}");`));
139
+ }
140
+ else {
141
+ // Variable part: only printable if it is a non-function value in scope.
142
+ const match = variables.find((v) => v.name === part.value && !v.isFunction);
143
+ if (match) {
144
+ const { spec, arg } = formatSpecFor(match.name, match.cppType);
145
+ lines.push(raw(` printf("${spec}", ${arg});`));
146
+ }
147
+ else {
148
+ lines.push(raw(` printf("%s", "{${escapeCppStringLiteral(part.value)}}"); // variable not in scope`));
149
+ }
150
+ }
151
+ }
152
+ lines.push(raw(` printf("\\n");`));
153
+ lines.push(` // === END LOGPOINT ===`);
154
+ return lines;
155
+ }
156
+ /**
157
+ * Pick a printf format specifier + argument expression for a debug variable.
158
+ *
159
+ * The debug preprocessor has no TypeChecker, so `cppType` is a coarse
160
+ * category inferred from AST shape. Native/generic mappings:
161
+ * - bool → %d via static_cast<int>
162
+ * - int/long → %lld via static_cast<long long> (native `number` is long
163
+ * long; int32_t widens into the same cast)
164
+ * - float → %g via static_cast<double> (float literal widens)
165
+ * - string → %s via .c_str() (native strings are std::string)
166
+ * - unknown → %g via static_cast<double>, the documented fallback that
167
+ * compiles for any numeric/bool variable.
168
+ */
169
+ function formatSpecFor(varName, cppType) {
170
+ switch (cppType) {
171
+ case 'bool':
172
+ return { spec: '%d', arg: `static_cast<int>(${varName})` };
173
+ case 'int':
174
+ case 'long':
175
+ return { spec: '%lld', arg: `static_cast<long long>(${varName})` };
176
+ case 'float':
177
+ return { spec: '%g', arg: `static_cast<double>(${varName})` };
178
+ case 'string':
179
+ return { spec: '%s', arg: `${varName}.c_str()` };
180
+ case 'unknown':
181
+ default:
182
+ // Cast to double so printf compiles regardless of the real C++ type.
183
+ return { spec: '%g', arg: `static_cast<double>(${varName})` };
184
+ }
185
+ }
@@ -34,9 +34,6 @@ export declare class GenericStrategy implements PlatformStrategy {
34
34
  enumCastType(enumName: string): string | undefined;
35
35
  renderBoardDefinitionAccess(_chain: string[], _boardConstants?: BoardConstants): string | undefined;
36
36
  renderThrow(valueExpr: string): string;
37
- isConsoleCall(callee: string): boolean;
38
- transformConsoleCall(method: string, renderedArgs: string, forHeader: boolean): string;
39
- transformConsoleExpression(method: string, _renderedArgs: string): string | undefined;
40
37
  objectFieldInitializer(_fieldValue: ExpressionIR, _renderExpr: (e: ExpressionIR) => string): string | undefined;
41
38
  overrideClassFieldType(_fieldName: string, _normalizedType: string): string;
42
39
  reservedNames(): ReadonlySet<string>;
@@ -50,7 +47,6 @@ export declare class GenericStrategy implements PlatformStrategy {
50
47
  needsStdFunction(): boolean;
51
48
  mathHeader(): string;
52
49
  cstringHeader(): string;
53
- needsVectorOverload(): boolean;
54
50
  needsLargeEnumUnderlying(): boolean;
55
51
  renameStructField(fieldName: string): string;
56
52
  structFieldInitializer(_fieldValue: ExpressionIR, _compiletimeVarNames: Set<string>, _renderExpr: (e: ExpressionIR) => string): string | undefined;
@@ -79,8 +75,10 @@ export declare class GenericStrategy implements PlatformStrategy {
79
75
  variables: Array<{
80
76
  name: string;
81
77
  isFunction?: boolean;
78
+ cppType?: 'bool' | 'int' | 'long' | 'float' | 'string' | 'unknown';
82
79
  }>;
83
80
  normalizedCondition?: string;
81
+ breakpointId?: number;
84
82
  }): string[];
85
83
  generateDebugLogpointCode(params: {
86
84
  fileName: string;
@@ -92,6 +90,7 @@ export declare class GenericStrategy implements PlatformStrategy {
92
90
  variables: Array<{
93
91
  name: string;
94
92
  isFunction?: boolean;
93
+ cppType?: 'bool' | 'int' | 'long' | 'float' | 'string' | 'unknown';
95
94
  }>;
96
95
  }): string[];
97
96
  resolveDisplayOp(_op: DisplayHALOp): {
@@ -1,7 +1,7 @@
1
1
  // ---------------------------------------------------------------------------
2
- // GenericStrategy — standard C++ target (std::cout, main(), <cmath> …)
2
+ // GenericStrategy — standard C++ target (main(), <cmath> …)
3
3
  // ---------------------------------------------------------------------------
4
- import { escapeCppStringLiteral } from "../utils/strings.js";
4
+ import { generateGenericInitCode, generateGenericBreakpointCode, generateGenericLogpointCode } from "./generic-debug-codegen.js";
5
5
  import { DEFAULT_STDLIB_SUPPORT } from "../api/shared/index.js";
6
6
  import { parsedIsPointer } from "../api/shared/cpp-type-ir.js";
7
7
  import { buildAsyncRuntimePolyfill } from "./async-runtime.js";
@@ -105,37 +105,6 @@ export class GenericStrategy {
105
105
  renderThrow(valueExpr) {
106
106
  return `throw ${valueExpr};`;
107
107
  }
108
- isConsoleCall(callee) {
109
- return callee.startsWith("console.");
110
- }
111
- transformConsoleCall(method, renderedArgs, forHeader) {
112
- const semi = forHeader ? "" : ";";
113
- switch (method) {
114
- case "log":
115
- case "info":
116
- case "debug":
117
- return `std::cout << ${renderedArgs} << std::endl${semi}`;
118
- case "error":
119
- return `std::cerr << "[ERROR] " << ${renderedArgs} << std::endl${semi}`;
120
- case "warn":
121
- return `std::cerr << "[WARN] " << ${renderedArgs} << std::endl${semi}`;
122
- case "readLine":
123
- case "readCharacter":
124
- return this.transformConsoleExpression(method, renderedArgs) + semi;
125
- default:
126
- return `std::cout << ${renderedArgs} << std::endl${semi}`;
127
- }
128
- }
129
- transformConsoleExpression(method, _renderedArgs) {
130
- switch (method) {
131
- case 'readLine':
132
- return '([]() -> std::string { std::string s; std::getline(std::cin, s); return s; })()';
133
- case 'readCharacter':
134
- return '([&]() -> char { std::cout << "> " << std::flush; return std::cin.get(); })()';
135
- default:
136
- return undefined;
137
- }
138
- }
139
108
  objectFieldInitializer(_fieldValue, _renderExpr) {
140
109
  return undefined;
141
110
  }
@@ -163,7 +132,6 @@ export class GenericStrategy {
163
132
  needsStdFunction() { return true; }
164
133
  mathHeader() { return "<cmath>"; }
165
134
  cstringHeader() { return "<cstring>"; }
166
- needsVectorOverload() { return true; }
167
135
  // ── Enum underlying type ────────────────────────────────────────────────
168
136
  needsLargeEnumUnderlying() { return false; }
169
137
  // ── Struct field handling ───────────────────────────────────────────────
@@ -227,56 +195,13 @@ export class GenericStrategy {
227
195
  return 'printf';
228
196
  }
229
197
  generateDebugInitCode() {
230
- return [
231
- '// === DEBUG: Initialize ===',
232
- 'std::cout << "TypeCAD Debug Mode Active" << std::endl;',
233
- '// === END DEBUG INIT ===',
234
- '',
235
- ];
198
+ return generateGenericInitCode();
236
199
  }
237
200
  generateDebugBreakpointCode(params) {
238
- const lines = [];
239
- lines.push(` // === BREAKPOINT: ${params.fileName}:${params.lineNum} ===`);
240
- if (params.normalizedCondition) {
241
- lines.push(` if (${params.normalizedCondition}) {`);
242
- }
243
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;`);
244
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << "BREAKPOINT: ${params.fileName}:${params.lineNum}" << std::endl;`);
245
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " ${params.originalLine.replace(/"/g, '\\"')}" << std::endl;`);
246
- if (params.variables.length > 0) {
247
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " Variables:" << std::endl;`);
248
- for (const v of params.variables) {
249
- if (v.isFunction) {
250
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " ${v.name} = [function]" << std::endl;`);
251
- }
252
- else {
253
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << " ${v.name} = " << ${v.name} << std::endl;`);
254
- }
255
- }
256
- }
257
- lines.push(` ${params.normalizedCondition ? ' ' : ''}std::cout << "━━━━━━━━━━━━━━━━━━━━━━━━━━━━" << std::endl;`);
258
- if (params.normalizedCondition) {
259
- lines.push(` }`);
260
- }
261
- lines.push(` // === END BREAKPOINT ===`);
262
- return lines;
201
+ return generateGenericBreakpointCode(params.fileName, params.lineNum, params.originalLine, params.variables, params.normalizedCondition, params.breakpointId);
263
202
  }
264
203
  generateDebugLogpointCode(params) {
265
- const lines = [];
266
- lines.push(` // === LOGPOINT: ${params.fileName}:${params.lineNum} ===`);
267
- const parts = [`"[LOG ${params.fileName}:${params.lineNum}] "`];
268
- for (const part of params.parts) {
269
- if (part.type === 'text') {
270
- parts.push(`"${escapeCppStringLiteral(part.value)}"`);
271
- }
272
- else {
273
- const varExists = params.variables.some(v => v.name === part.value && !v.isFunction);
274
- parts.push(varExists ? part.value : `"${escapeCppStringLiteral(part.value)}"`);
275
- }
276
- }
277
- lines.push(` std::cout << ${parts.join(' << ')} << std::endl;`);
278
- lines.push(` // === END LOGPOINT ===`);
279
- return lines;
204
+ return generateGenericLogpointCode(params.fileName, params.lineNum, params.parts, params.variables);
280
205
  }
281
206
  // ── Graphics (fallback) ────────────────────────────────────────────────
282
207
  resolveDisplayOp(_op) {
@@ -2,7 +2,7 @@
2
2
  // Platform strategy exports
3
3
  //
4
4
  // Re-exports platform strategies for use within the CLI and by consumers.
5
- // Framework-specific strategies (e.g. ArduinoStrategy) are provided by their
5
+ // Framework-specific strategies (e.g. ZephyrStrategy) are provided by their
6
6
  // respective framework packages, which register via registerPlatformStrategy().
7
7
  // ---------------------------------------------------------------------------
8
8
  export { GenericStrategy } from './generic-strategy.js';
@@ -4,9 +4,9 @@ import type { PlatformStrategy } from "../api/shared/index.js";
4
4
  * their entry point to override the default strategy for a target.
5
5
  *
6
6
  * @example
7
- * // In @typecad/framework-arduino
7
+ * // In @typecad/framework-zephyr
8
8
  * import { registerPlatformStrategy } from "@typecad/cuttlefish/platform/registry";
9
- * registerPlatformStrategy(new ArduinoStrategy());
9
+ * registerPlatformStrategy(new ZephyrStrategy());
10
10
  */
11
11
  export declare function registerPlatformStrategy(strategy: PlatformStrategy): void;
12
12
  /**
@@ -15,9 +15,9 @@ const _registry = new Map([
15
15
  * their entry point to override the default strategy for a target.
16
16
  *
17
17
  * @example
18
- * // In @typecad/framework-arduino
18
+ * // In @typecad/framework-zephyr
19
19
  * import { registerPlatformStrategy } from "@typecad/cuttlefish/platform/registry";
20
- * registerPlatformStrategy(new ArduinoStrategy());
20
+ * registerPlatformStrategy(new ZephyrStrategy());
21
21
  */
22
22
  export function registerPlatformStrategy(strategy) {
23
23
  _registry.set(strategy.id, strategy);
@@ -8,6 +8,9 @@ let pendingPointerFrame = 0;
8
8
  let debugModes = { boxes: false, clips: false, dirty: false, inspect: false };
9
9
  let debugOverlay;
10
10
  let debugCtx;
11
+ /** Re-syncs the overlay to the app canvas whenever layout changes its box
12
+ * (aspect-ratio application, max-height, container reflow). */
13
+ let overlayResizeObserver;
11
14
  let dirtyFlashAlpha = 0;
12
15
  /** CSS px per logical display px — the overlay backing store runs at this
13
16
  * resolution so debug strokes are 1 CSS px thin (a 1-logical-px stroke on
@@ -263,11 +266,22 @@ async function start() {
263
266
  debugOverlay.height = Math.max(1, Math.round(rect.height * dpr));
264
267
  debugScale = (rect.width * dpr) / snapshot.program.width;
265
268
  };
266
- syncOverlayBox();
267
- window.addEventListener("resize", syncOverlayBox);
268
269
  // Set the canvas CSS aspect-ratio to match the display (e.g. 128:64 for
269
- // OLED, 320:240 for TFT) so the browser scales it proportionally.
270
+ // OLED, 320:240 for TFT) BEFORE syncing the overlay: the canvas is
271
+ // vertically centered (place-items: center), so applying the real aspect
272
+ // after the sync SHRANK it and moved it DOWN — the overlay stayed at the
273
+ // old 4/3-fallback position and every debug box sat that far above its
274
+ // element. A ResizeObserver re-syncs on any later layout-driven size
275
+ // change (max-height kicking in, container reflow), not just window
276
+ // resizes.
270
277
  document.documentElement.style.setProperty("--display-aspect", `${snapshot.program.width} / ${snapshot.program.height}`);
278
+ syncOverlayBox();
279
+ window.addEventListener("resize", syncOverlayBox);
280
+ if (typeof ResizeObserver !== "undefined") {
281
+ overlayResizeObserver?.disconnect();
282
+ overlayResizeObserver = new ResizeObserver(() => syncOverlayBox());
283
+ overlayResizeObserver.observe(canvas);
284
+ }
271
285
  const status = byId("status");
272
286
  status.textContent = `${snapshot.profileName ?? snapshot.program.display?.driver ?? "display"} ${snapshot.program.width}x${snapshot.program.height} ${snapshot.program.colorFormat}`;
273
287
  const extraDiagnostics = [];
@@ -0,0 +1,32 @@
1
+ export {};
2
+ /** ASIL level annotations for functions — comment-based.
3
+ *
4
+ * ASIL levels are declared via leading comment annotations rather than
5
+ * TypeScript decorators because:
6
+ * - TS decorators on function declarations produce TS1206 errors in the
7
+ * VS Code language server and @typescript-eslint/parser
8
+ * - Comment annotations work in any editor, any toolchain, without
9
+ * `experimentalDecorators` or special config
10
+ *
11
+ * The cuttlefish IR builder extracts these from leading comments via
12
+ * extractAsilFromComments() in function-builder.ts.
13
+ *
14
+ * Part B's ISO 26262 checkers (analyzeIR) read the resulting `decorators`
15
+ * field on FunctionIR to decide which rules to enforce:
16
+ *
17
+ * // @asilD → all rules enforced (recursion, heap, loops)
18
+ * // @asilC → recursion + loops enforced (heap is ASIL D only)
19
+ * // @asilB → recursion enforced
20
+ * // @asilA → no rules enforced (quality-managed)
21
+ * (no annotation) → no rules enforced (implicit QM)
22
+ *
23
+ * Usage:
24
+ * // @asilD
25
+ * function engageBrake(): void {
26
+ * safe.write(brakePin, 1);
27
+ * }
28
+ *
29
+ * These are documentation-only exports — they have no runtime behavior
30
+ * and are never imported by user code. They exist so the ASIL level
31
+ * names appear in type hints and IDE autocomplete.
32
+ */