@typecad/cuttlefish 0.1.0-alpha.2 → 1.0.0-alpha.11

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 (224) hide show
  1. package/README.md +10 -10
  2. package/dist/api/board-types.d.ts +1 -1
  3. package/dist/api/config.d.ts +38 -2
  4. package/dist/api/index.d.ts +1 -1
  5. package/dist/api/schema/types.d.ts +15 -0
  6. package/dist/api/shared/async-runtime-static.d.ts +12 -1
  7. package/dist/api/shared/async-runtime-static.js +69 -24
  8. package/dist/api/shared/async-symbol-detector.d.ts +11 -0
  9. package/dist/api/shared/async-symbol-detector.js +140 -0
  10. package/dist/api/shared/async-types.d.ts +24 -0
  11. package/dist/api/shared/coop-scheduler.d.ts +60 -0
  12. package/dist/api/shared/coop-scheduler.js +149 -0
  13. package/dist/api/shared/display-adapter.d.ts +4 -3
  14. package/dist/api/shared/display-adapter.js +15 -118
  15. package/dist/api/shared/display-adapters/sdl.js +38 -31
  16. package/dist/api/shared/display-profile.d.ts +47 -25
  17. package/dist/api/shared/display-profile.js +31 -164
  18. package/dist/api/shared/framework-manifest-registry.d.ts +9 -0
  19. package/dist/api/shared/framework-manifest-registry.js +27 -0
  20. package/dist/api/shared/framework-manifest.d.ts +595 -0
  21. package/dist/api/shared/framework-manifest.js +193 -0
  22. package/dist/api/shared/glcdfont.d.ts +12 -0
  23. package/dist/api/shared/glcdfont.js +124 -0
  24. package/dist/api/shared/graphics-strategy.d.ts +37 -0
  25. package/dist/api/shared/hal-op-ir.d.ts +764 -1
  26. package/dist/api/shared/hal-op-ir.js +129 -1
  27. package/dist/api/shared/index.d.ts +22 -2
  28. package/dist/api/shared/index.js +26 -1
  29. package/dist/api/shared/ir-core.d.ts +4 -0
  30. package/dist/api/shared/ir-declarations.d.ts +6 -0
  31. package/dist/api/shared/native-display-op-resolver.d.ts +10 -0
  32. package/dist/api/shared/native-display-op-resolver.js +64 -0
  33. package/dist/api/shared/platform-strategy.d.ts +119 -2
  34. package/dist/api/shared/polyfill-helper-registry.js +18 -1
  35. package/dist/api/shared/promise-runtime.d.ts +1 -1
  36. package/dist/api/shared/promise-runtime.js +95 -13
  37. package/dist/api/shared/spdx-licenses.d.ts +139 -0
  38. package/dist/api/shared/spdx-licenses.js +385 -0
  39. package/dist/api/shared/toolchain-types.d.ts +17 -0
  40. package/dist/api/shared/types.d.ts +8 -0
  41. package/dist/api/shared/validate-framework-manifest.d.ts +28 -0
  42. package/dist/api/shared/validate-framework-manifest.js +494 -0
  43. package/dist/api/shared/worker-runtime-polyfill.d.ts +22 -0
  44. package/dist/api/shared/worker-runtime-polyfill.js +34 -0
  45. package/dist/api/shared/worker-runtime.d.ts +69 -0
  46. package/dist/api/shared/worker-runtime.js +163 -0
  47. package/dist/cli-utils.d.ts +1 -0
  48. package/dist/cli-utils.js +3 -1
  49. package/dist/cli.js +249 -32
  50. package/dist/config-loader.d.ts +7 -2
  51. package/dist/config-loader.js +23 -3
  52. package/dist/config-schema.d.ts +112 -70
  53. package/dist/config-schema.js +14 -0
  54. package/dist/contract/board-generator.d.ts +17 -0
  55. package/dist/contract/board-generator.js +57 -0
  56. package/dist/contract/contract-parser.d.ts +217 -0
  57. package/dist/contract/contract-parser.js +224 -0
  58. package/dist/contract/index.d.ts +22 -0
  59. package/dist/contract/index.js +68 -0
  60. package/dist/create/board-codegen.js +4 -4
  61. package/dist/create/board-generators.js +4 -5
  62. package/dist/create/board-spec.d.ts +72 -75
  63. package/dist/create/board-spec.js +0 -1
  64. package/dist/create/framework-catalog.d.ts +64 -0
  65. package/dist/create/framework-catalog.js +136 -0
  66. package/dist/create/index.d.ts +5 -1
  67. package/dist/create/index.js +3 -1
  68. package/dist/create/init-scaffold.d.ts +12 -3
  69. package/dist/create/init-scaffold.js +49 -14
  70. package/dist/create/init-templates.d.ts +4 -0
  71. package/dist/create/init-templates.js +271 -17
  72. package/dist/create/init-wizard.js +41 -27
  73. package/dist/create/install-deps.d.ts +32 -0
  74. package/dist/create/install-deps.js +46 -0
  75. package/dist/debug/preprocessor.js +178 -39
  76. package/dist/debug/types.d.ts +23 -0
  77. package/dist/diagnostics/mermaid-builder.d.ts +1 -1
  78. package/dist/diagnostics/mermaid-builder.js +34 -24
  79. package/dist/emit/compliance/arxml-writer.d.ts +11 -0
  80. package/dist/emit/compliance/arxml-writer.js +34 -0
  81. package/dist/emit/compliance/compliance-context.d.ts +57 -0
  82. package/dist/emit/compliance/compliance-context.js +113 -0
  83. package/dist/emit/compliance/deviation-ledger.d.ts +27 -0
  84. package/dist/emit/compliance/deviation-ledger.js +47 -0
  85. package/dist/emit/compliance/deviation-writer.d.ts +30 -0
  86. package/dist/emit/compliance/deviation-writer.js +37 -0
  87. package/dist/emit/compliance/index.d.ts +7 -0
  88. package/dist/emit/compliance/index.js +6 -0
  89. package/dist/emit/compliance/rule-engine.d.ts +13 -0
  90. package/dist/emit/compliance/rule-engine.js +101 -0
  91. package/dist/emit/compliance/rules.d.ts +16 -0
  92. package/dist/emit/compliance/rules.js +191 -0
  93. package/dist/emit/compliance/types.d.ts +59 -0
  94. package/dist/emit/compliance/types.js +8 -0
  95. package/dist/emit/cpp-emitter.js +4 -3
  96. package/dist/emit/emitters/class-emitter.js +6 -1
  97. package/dist/emit/emitters/emitter-context.d.ts +28 -1
  98. package/dist/emit/emitters/function-emitter-impl.js +153 -53
  99. package/dist/emit/emitters/line-appender.js +19 -0
  100. package/dist/emit/emitters/line-marker.d.ts +38 -0
  101. package/dist/emit/emitters/line-marker.js +39 -0
  102. package/dist/emit/emitters/output-finalizer.d.ts +6 -0
  103. package/dist/emit/emitters/output-finalizer.js +101 -12
  104. package/dist/emit/emitters/setup.d.ts +17 -0
  105. package/dist/emit/emitters/setup.js +372 -30
  106. package/dist/emit/emitters/top-level-prep.js +8 -0
  107. package/dist/emit/emitters/type-decl-emitter.js +28 -3
  108. package/dist/emit/emitters/ui-emitter.js +33 -9
  109. package/dist/emit/expression-renderer.d.ts +1 -1
  110. package/dist/emit/expression-renderer.js +91 -6
  111. package/dist/emit/route-hal-op.js +18 -5
  112. package/dist/emit/snprintf-helpers.js +15 -4
  113. package/dist/emit/statement-renderer.d.ts +10 -0
  114. package/dist/emit/statement-renderer.js +34 -5
  115. package/dist/emit/utils/async-state-machine.js +221 -125
  116. package/dist/emit/utils/hal-op-cpp-type.d.ts +6 -0
  117. package/dist/emit/utils/hal-op-cpp-type.js +40 -0
  118. package/dist/framework-package.js +2 -0
  119. package/dist/framework-registry.d.ts +17 -0
  120. package/dist/install/framework-catalog.d.ts +53 -0
  121. package/dist/install/framework-catalog.js +107 -0
  122. package/dist/install/handle-install.d.ts +35 -0
  123. package/dist/install/handle-install.js +177 -0
  124. package/dist/install/index.d.ts +4 -0
  125. package/dist/install/index.js +3 -0
  126. package/dist/ir/adc-range-validation.js +40 -26
  127. package/dist/ir/build-ir-state.d.ts +1 -0
  128. package/dist/ir/build-ir-state.js +14 -0
  129. package/dist/ir/build-ir.js +9 -5
  130. package/dist/ir/call-graph.js +16 -0
  131. package/dist/ir/expression-to-ir.js +207 -6
  132. package/dist/ir/feature-registry.js +7 -25
  133. package/dist/ir/function-builder.js +22 -0
  134. package/dist/ir/hal/hal-emitter.d.ts +5 -2
  135. package/dist/ir/hal/hal-emitter.js +50 -18
  136. package/dist/ir/hal/hal-parser.d.ts +6 -0
  137. package/dist/ir/hal/hal-parser.js +81 -0
  138. package/dist/ir/hal/hal-plugins.js +733 -1
  139. package/dist/ir/identifier-collector.js +35 -0
  140. package/dist/ir/interrupt-analysis.d.ts +5 -1
  141. package/dist/ir/interrupt-analysis.js +16 -19
  142. package/dist/ir/memory-budget-validation.js +1 -0
  143. package/dist/ir/network-validation.d.ts +4 -0
  144. package/dist/ir/network-validation.js +184 -0
  145. package/dist/ir/ownership-analysis.js +39 -1
  146. package/dist/ir/peripheral-ownership.js +5 -0
  147. package/dist/ir/peripheral-validation.d.ts +1 -1
  148. package/dist/ir/peripheral-validation.js +6 -3
  149. package/dist/ir/pin-alias-conflict.d.ts +1 -1
  150. package/dist/ir/pin-alias-conflict.js +2 -1
  151. package/dist/ir/pin-capability-validation.js +71 -32
  152. package/dist/ir/pin-mode-validation.d.ts +2 -2
  153. package/dist/ir/pin-mode-validation.js +54 -18
  154. package/dist/ir/pin-safety.d.ts +1 -1
  155. package/dist/ir/pin-safety.js +2 -1
  156. package/dist/ir/program-analysis.d.ts +81 -0
  157. package/dist/ir/program-analysis.js +429 -0
  158. package/dist/ir/pulldown-validation.d.ts +1 -1
  159. package/dist/ir/pulldown-validation.js +2 -1
  160. package/dist/ir/pwm-timer-sharing.d.ts +1 -1
  161. package/dist/ir/pwm-timer-sharing.js +2 -1
  162. package/dist/ir/render-expr.js +11 -0
  163. package/dist/ir/resource-analysis.js +2 -0
  164. package/dist/ir/timer0-pwm-timing-conflict.d.ts +1 -1
  165. package/dist/ir/timer0-pwm-timing-conflict.js +2 -1
  166. package/dist/ir/timing-validation.d.ts +6 -1
  167. package/dist/ir/timing-validation.js +61 -13
  168. package/dist/ir/transformers/call-statement.js +105 -0
  169. package/dist/ir/transformers/expressions.js +62 -0
  170. package/dist/ir/transformers/hal-call-resolver.js +21 -0
  171. package/dist/ir/transformers/hal-emit-helpers.js +1 -1
  172. package/dist/ir/transformers/namespace-methods.js +17 -12
  173. package/dist/ir/transformers/ui-reactive.js +2 -2
  174. package/dist/ir/transformers/variables.js +137 -19
  175. package/dist/ir/try-catch-validation.js +2 -0
  176. package/dist/ir/type-resolution.js +20 -2
  177. package/dist/ir/ui-element-auto-wire.js +7 -5
  178. package/dist/ir/unit-suspicion-validation.js +9 -7
  179. package/dist/ir/utils/map-statements.d.ts +4 -0
  180. package/dist/ir/utils/map-statements.js +79 -0
  181. package/dist/ir/validation-orchestrator.js +15 -8
  182. package/dist/ir/worker-analysis.d.ts +10 -0
  183. package/dist/ir/worker-analysis.js +261 -0
  184. package/dist/libdef/c-to-decl.d.ts +27 -0
  185. package/dist/libdef/c-to-decl.js +397 -0
  186. package/dist/libdef/component-decls.d.ts +2 -0
  187. package/dist/libdef/component-decls.js +6 -0
  188. package/dist/libdef/component-discovery.d.ts +43 -0
  189. package/dist/libdef/component-discovery.js +83 -0
  190. package/dist/libdef/cpp-to-decl.d.ts +9 -0
  191. package/dist/libdef/cpp-to-decl.js +72 -0
  192. package/dist/libdef/registry.js +5 -2
  193. package/dist/lint-cache.d.ts +59 -0
  194. package/dist/lint-cache.js +257 -0
  195. package/dist/orchestrator/graph-builder.js +14 -9
  196. package/dist/platform/coop-scheduler-runtime.d.ts +19 -0
  197. package/dist/platform/coop-scheduler-runtime.js +41 -0
  198. package/dist/platform/generic-strategy.d.ts +15 -3
  199. package/dist/platform/generic-strategy.js +49 -4
  200. package/dist/safety/safety-bridge.d.ts +11 -0
  201. package/dist/safety/safety-bridge.js +48 -0
  202. package/dist/safety/sidecar-bridge.d.ts +5 -0
  203. package/dist/safety/sidecar-bridge.js +22 -0
  204. package/dist/safety-hook.d.ts +79 -0
  205. package/dist/safety-hook.js +35 -0
  206. package/dist/testing.d.ts +8 -2
  207. package/dist/testing.js +9 -2
  208. package/dist/transpile.d.ts +3 -0
  209. package/dist/transpile.js +191 -49
  210. package/dist/types.d.ts +22 -3
  211. package/dist/ui-hook.d.ts +17 -3
  212. package/dist/utils/cli.js +123 -2
  213. package/dist/utils/fs.d.ts +13 -0
  214. package/dist/utils/fs.js +50 -0
  215. package/dist/utils/ui.js +3 -1
  216. package/package.json +23 -3
  217. package/dist/api/shared/display-adapters/eink-mono.d.ts +0 -2
  218. package/dist/api/shared/display-adapters/eink-mono.js +0 -53
  219. package/dist/api/shared/display-adapters/ssd1309.d.ts +0 -2
  220. package/dist/api/shared/display-adapters/ssd1309.js +0 -136
  221. package/dist/api/shared/display-adapters/st7796.d.ts +0 -2
  222. package/dist/api/shared/display-adapters/st7796.js +0 -132
  223. package/dist/ir/heap-array-validation.d.ts +0 -24
  224. package/dist/ir/heap-array-validation.js +0 -29
@@ -25,43 +25,13 @@ const RESISTIVE_TOUCH_LIBS = new Set([
25
25
  "XPT2046_Touchscreen",
26
26
  "Adafruit_TouchScreen",
27
27
  ]);
28
- /** Default RGB565 scroll viewport canvas budget (~88 KB, ESP32-class SRAM). */
29
- export const DEFAULT_SCROLL_CANVAS_BUDGET_BYTES = 88000;
30
- /** PSRAM scroll canvas budget (~2 MB). ESP32-S3 with OPI/QSPI PSRAM exposes
31
- * ~8 MB external RAM; a full-width scroll viewport canvas (e.g. 460×266×2 ≈
32
- * 239 KB) is trivial there, so the transpile-time scroll-canvas-memory
33
- * diagnostic should use a PSRAM-appropriate budget rather than the no-PSRAM
34
- * SRAM default — otherwise every PSRAM target emits stale "exceeds budget"
35
- * warnings for canvases the runtime allocates without issue. */
36
- export const PSRAM_SCROLL_CANVAS_BUDGET_BYTES = 2_000_000;
37
- /** Detect PSRAM from an Arduino FQBN buildTarget (e.g. "esp32:esp32:esp32s3:PSRAM=opi").
38
- * Returns true for any PSRAM=<value> option whose value indicates PSRAM is
39
- * enabled (opi, io, qspi, enabled, true). Returns false when absent or set
40
- * to a disabled-looking value (disabled, false, none). */
41
- export function buildTargetHasPsram(buildTarget) {
42
- if (!buildTarget)
43
- return false;
44
- const opts = buildTarget.split(":");
45
- for (const opt of opts) {
46
- const eq = opt.indexOf("=");
47
- if (eq < 0)
48
- continue;
49
- const key = opt.slice(0, eq).trim().toLowerCase();
50
- const val = opt.slice(eq + 1).trim().toLowerCase();
51
- if (key !== "psram")
52
- continue;
53
- // Any explicit PSRAM option except an explicit disabled value means PSRAM.
54
- return !["disabled", "false", "none", "no", "0"].includes(val);
55
- }
56
- return false;
57
- }
58
28
  /**
59
29
  * Resolve scroll config from a display profile. Declared overrides win;
60
30
  * otherwise derive the input tier from the touch library (resistive chips →
61
31
  * "resistive", any other touch → "capacitive", no touch → "none") and assume a
62
32
  * full render tier (ESP32-class SRAM can fit a viewport canvas).
63
33
  */
64
- export function resolveScrollConfig(display, ctx) {
34
+ export function resolveScrollConfig(display) {
65
35
  const s = display.scroll ?? {};
66
36
  const lib = display.touch && typeof display.touch === "object"
67
37
  ? display.touch.library
@@ -71,14 +41,6 @@ export function resolveScrollConfig(display, ctx) {
71
41
  : display.touch
72
42
  ? "capacitive"
73
43
  : "none";
74
- // PSRAM-aware canvas budget: an explicit override always wins; otherwise use
75
- // the PSRAM budget when the build target opts into PSRAM (so the scroll-canvas-
76
- // memory diagnostic doesn't emit stale warnings for canvases the runtime
77
- // allocates in external RAM without issue), else the no-PSRAM SRAM default.
78
- const psramBudget = buildTargetHasPsram(ctx?.buildTarget);
79
- const budgetDefault = psramBudget
80
- ? PSRAM_SCROLL_CANVAS_BUDGET_BYTES
81
- : DEFAULT_SCROLL_CANVAS_BUDGET_BYTES;
82
44
  return {
83
45
  inputTier: s.inputTier ?? derivedInput,
84
46
  renderTier: s.renderTier ?? "full",
@@ -89,7 +51,6 @@ export function resolveScrollConfig(display, ctx) {
89
51
  inputSmoothing: s.inputSmoothing ?? 0.3,
90
52
  overrideProbes: s.overrideProbes ?? true,
91
53
  debug: s.debug ?? false,
92
- scrollCanvasBudgetBytes: s.scrollCanvasBudgetBytes ?? budgetDefault,
93
54
  };
94
55
  }
95
56
  export function resolveDisplayProfile(config, registry) {
@@ -151,6 +112,8 @@ export function resolveDisplayProfile(config, registry) {
151
112
  base.colorOrder = config.colorOrder;
152
113
  if (config.invertDisplay !== undefined)
153
114
  base.invertDisplay = config.invertDisplay;
115
+ if (config.scanlineSync !== undefined)
116
+ base.scanlineSync = config.scanlineSync;
154
117
  if (config.touch === false)
155
118
  base.touch = undefined;
156
119
  else if (config.touch !== undefined)
@@ -176,125 +139,26 @@ export function resolveDisplayProfile(config, registry) {
176
139
  reset: config.reset ?? -1,
177
140
  };
178
141
  }
179
- /** Generate C++ code for a built-in touch library adapter. */
180
- export function generateTouchAdapter(touch) {
181
- const cs = touch.cs ?? 0;
182
- const irq = touch.irq;
183
- if (touch.library === "XPT2046_Touchscreen") {
184
- return {
185
- includes: ["#include <XPT2046_Touchscreen.h>"],
186
- declaration: `XPT2046_Touchscreen __tc_touch(${cs}${irq ? `, ${irq}` : ""});`,
187
- functions: [
188
- `static inline void touch_init() { __tc_touch.begin(); }`,
189
- `static inline bool touch_isTouched() { return __tc_touch.touched(); }`,
190
- `static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
191
- ` TS_Point __tp = __tc_touch.getPoint();`,
192
- ` if (x) *x = (int16_t)__tp.x;`,
193
- ` if (y) *y = (int16_t)__tp.y;`,
194
- ` if (z) *z = (int16_t)__tp.z;`,
195
- `}`,
196
- ].join("\n"),
197
- };
198
- }
199
- if (touch.library === "Adafruit_TouchScreen" && touch.analogPins) {
200
- const a = touch.analogPins;
201
- return {
202
- includes: ["#include <TouchScreen.h>"],
203
- declaration: `TouchScreen __tc_touch = TouchScreen(${a.xp}, ${a.yp}, ${a.xm}, ${a.ym}, ${a.rx});`,
204
- functions: [
205
- `static inline void touch_init() {}`,
206
- `static inline bool touch_isTouched() { return __tc_touch.isTouching(); }`,
207
- `static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
208
- ` TS_Point __tp = __tc_touch.getPoint();`,
209
- ` if (x) *x = (int16_t)__tp.x;`,
210
- ` if (y) *y = (int16_t)__tp.y;`,
211
- ` if (z) *z = (int16_t)__tp.z;`,
212
- `}`,
213
- ].join("\n"),
214
- };
215
- }
216
- if (touch.library === "Adafruit_STMPE610") {
217
- return {
218
- includes: ["#include <Adafruit_STMPE610.h>"],
219
- declaration: `Adafruit_STMPE610 __tc_touch(${cs});`,
220
- functions: [
221
- `static inline void touch_init() { __tc_touch.begin(); }`,
222
- `static inline bool touch_isTouched() { return __tc_touch.touched() && !__tc_touch.bufferEmpty(); }`,
223
- `static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
224
- ` TS_Point __tp = __tc_touch.getPoint();`,
225
- ` if (x) *x = (int16_t)__tp.x;`,
226
- ` if (y) *y = (int16_t)__tp.y;`,
227
- ` if (z) *z = (int16_t)__tp.z;`,
228
- `}`,
229
- ].join("\n"),
230
- };
231
- }
232
- if (touch.library === "FT6336U") {
233
- const addr = touch.i2cAddress ?? 0x38;
234
- // I2C addresses are conventional in hex in Arduino code.
235
- const addrHex = "0x" + addr.toString(16).toUpperCase();
236
- const i2cFrequency = touch.i2cFrequency ?? 400000;
237
- const reset = touch.resetPin;
238
- const resetLines = reset
239
- ? [
240
- ` pinMode(${reset}, OUTPUT);`,
241
- ` digitalWrite(${reset}, LOW);`,
242
- ` delay(10);`,
243
- ` digitalWrite(${reset}, HIGH);`,
244
- ` delay(500);`,
245
- ].join("\n")
246
- : ``;
247
- return {
248
- includes: ["#include <Wire.h>", "#include <RAK14014_FT6336U.h>"],
249
- declaration: [
250
- `FT6336U __tc_touch(${addrHex});`,
251
- `static int16_t __tc_touch_cached_x = 0;`,
252
- `static int16_t __tc_touch_cached_y = 0;`,
253
- `static int16_t __tc_touch_cached_z = 0;`,
254
- `static uint8_t __tc_touch_cached_valid = 0;`,
255
- ].join("\n"),
256
- functions: [
257
- `static inline uint8_t __tc_ft6336u_read_block(uint8_t reg, uint8_t* buf, uint8_t len) {`,
258
- ` Wire.beginTransmission(${addrHex});`,
259
- ` Wire.write(reg);`,
260
- ` if (Wire.endTransmission(false) != 0) return 0;`,
261
- ` uint8_t got = Wire.requestFrom((uint8_t)${addrHex}, len);`,
262
- ` if (got < len) return 0;`,
263
- ` for (uint8_t i = 0; i < len; i++) {`,
264
- ` if (!Wire.available()) return 0;`,
265
- ` buf[i] = Wire.read();`,
266
- ` }`,
267
- ` return 1;`,
268
- `}`,
269
- `static inline void touch_init() {`,
270
- resetLines,
271
- ` __tc_touch.begin(Wire, ${addrHex});`,
272
- ` Wire.setClock(${i2cFrequency});`,
273
- `}`,
274
- `static inline bool touch_isTouched() {`,
275
- ` uint8_t buf[5] = {0, 0, 0, 0, 0};`,
276
- ` __tc_touch_cached_valid = 0;`,
277
- ` __tc_touch_cached_z = 0;`,
278
- ` if (!__tc_ft6336u_read_block(0x02, buf, 5)) return false;`,
279
- ` uint8_t count = buf[0] & 0x0F;`,
280
- ` if (count == 0) return false;`,
281
- ` __tc_touch_cached_x = (int16_t)(((uint16_t)(buf[1] & 0x0F) << 8) | buf[2]);`,
282
- ` __tc_touch_cached_y = (int16_t)(((uint16_t)(buf[3] & 0x0F) << 8) | buf[4]);`,
283
- ` __tc_touch_cached_z = 255;`,
284
- ` __tc_touch_cached_valid = 1;`,
285
- ` return true;`,
286
- `}`,
287
- `static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
288
- ` if (!__tc_touch_cached_valid) {`,
289
- ` (void)touch_isTouched();`,
290
- ` }`,
291
- ` if (x) *x = __tc_touch_cached_x;`,
292
- ` if (y) *y = __tc_touch_cached_y;`,
293
- ` if (z) *z = __tc_touch_cached_z;`,
294
- ` __tc_touch_cached_valid = 0;`,
295
- `}`,
296
- ].join("\n"),
297
- };
142
+ /** Generate C++ code for a built-in touch library adapter.
143
+ *
144
+ * Strategy-owned touch adapters take precedence: when the strategy's
145
+ * `providesTouchAdapter()` returns true and `resolveTouchAdapter` returns
146
+ * non-null, that codegen wins. The Arduino-ecosystem libraries
147
+ * (XPT2046_Touchscreen, Adafruit_TouchScreen, Adafruit_STMPE610, FT6336U)
148
+ * are strategy-owned — they live in @typecad/framework-arduino
149
+ * (src/displays/touch-adapters-codegen.ts) and ArduinoStrategy dispatches to
150
+ * them. Cuttlefish keeps only the framework-agnostic `sdl` path here.
151
+ *
152
+ * Passing `undefined` for the strategy (or a strategy whose
153
+ * resolveTouchAdapter returns undefined for the given library) falls through
154
+ * to the `sdl` branch below; any other library without a strategy-provided
155
+ * adapter throws.
156
+ */
157
+ export function generateTouchAdapter(touch, strategy) {
158
+ if (strategy?.providesTouchAdapter?.() && strategy.resolveTouchAdapter) {
159
+ const code = strategy.resolveTouchAdapter(touch);
160
+ if (code)
161
+ return code;
298
162
  }
299
163
  if (touch.library === "sdl") {
300
164
  return {
@@ -325,14 +189,17 @@ export function generateTouchAdapter(touch) {
325
189
  ` int __ww = 0, __wh = 0; SDL_GetWindowSize(__tc_display.win, &__ww, &__wh);`,
326
190
  ` if (__ww <= 0) __ww = display_width();`,
327
191
  ` if (__wh <= 0) __wh = display_height();`,
328
- ` if (x) *x = (int16_t)((int32_t)__sdl_mouse_x * display_width() / __ww);`,
329
- ` if (y) *y = (int16_t)((int32_t)__sdl_mouse_y * display_height() / __wh);`,
192
+ ` if (x) *x = static_cast<int16_t>(static_cast<int32_t>(__sdl_mouse_x) * display_width() / __ww);`,
193
+ ` if (y) *y = static_cast<int16_t>(static_cast<int32_t>(__sdl_mouse_y) * display_height() / __wh);`,
330
194
  ` if (z) *z = 200; // constant > default minPressure (10)`,
331
195
  `}`,
332
196
  ].join("\n"),
333
197
  };
334
198
  }
335
- throw new Error(`Unknown touch library "${touch.library}". ` +
336
- `Use { adapter: './path' } for custom touch adapters, or one of: ` +
337
- `XPT2046_Touchscreen, Adafruit_TouchScreen, Adafruit_STMPE610, FT6336U, sdl.`);
199
+ throw new Error(`No touch adapter for library "${touch.library}". ` +
200
+ `The built-in Arduino touch libraries (XPT2046_Touchscreen, Adafruit_TouchScreen, ` +
201
+ `Adafruit_STMPE610, FT6336U) are provided by @typecad/framework-arduino — pass the ` +
202
+ `ArduinoStrategy (or another framework strategy that provides touch adapters) so its ` +
203
+ `resolveTouchAdapter can dispatch to them. Otherwise use the framework-agnostic ` +
204
+ `"sdl" library, or { adapter: './path' } for a custom touch adapter.`);
338
205
  }
@@ -0,0 +1,9 @@
1
+ import type { FrameworkManifest } from './framework-manifest.js';
2
+ export declare const KNOWN_FRAMEWORK_PACKAGES: readonly ["@typecad/framework-arduino", "@typecad/framework-zephyr"];
3
+ export type KnownFrameworkPackage = typeof KNOWN_FRAMEWORK_PACKAGES[number];
4
+ /**
5
+ * Loads a framework's manifest via its `./framework.manifest` subpath export.
6
+ * Throws if the package does not export that subpath or the export has no
7
+ * default value.
8
+ */
9
+ export declare function loadFrameworkManifest(packageName: string): Promise<FrameworkManifest>;
@@ -0,0 +1,27 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Framework manifest discovery
3
+ //
4
+ // KNOWN_FRAMEWORK_PACKAGES is the authoritative list of framework packages
5
+ // that ship a framework.manifest (i.e. participate in the manifest validation
6
+ // system). It names real packages by their npm scope+name so the manifest
7
+ // validator and coverage tooling can iterate them — it is not framework-
8
+ // specific knowledge. Add a new framework here when it ships a manifest.
9
+ // loadFrameworkManifest uses the "./framework.manifest" subpath export each
10
+ // framework declares in its package.json.
11
+ // ---------------------------------------------------------------------------
12
+ export const KNOWN_FRAMEWORK_PACKAGES = [
13
+ '@typecad/framework-arduino',
14
+ '@typecad/framework-zephyr',
15
+ ];
16
+ /**
17
+ * Loads a framework's manifest via its `./framework.manifest` subpath export.
18
+ * Throws if the package does not export that subpath or the export has no
19
+ * default value.
20
+ */
21
+ export async function loadFrameworkManifest(packageName) {
22
+ const mod = await import(/* @vite-ignore */ `${packageName}/framework.manifest`);
23
+ if (!mod.default) {
24
+ throw new Error(`Package ${packageName} does not export a default manifest from "./framework.manifest".`);
25
+ }
26
+ return mod.default;
27
+ }