@typecad/cuttlefish 1.0.0-alpha.7 → 1.0.0-alpha.9

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 (167) hide show
  1. package/dist/api/config.d.ts +32 -0
  2. package/dist/api/index.d.ts +1 -1
  3. package/dist/api/schema/types.d.ts +15 -0
  4. package/dist/api/shared/async-runtime-static.d.ts +12 -1
  5. package/dist/api/shared/async-runtime-static.js +69 -24
  6. package/dist/api/shared/async-symbol-detector.d.ts +11 -0
  7. package/dist/api/shared/async-symbol-detector.js +140 -0
  8. package/dist/api/shared/async-types.d.ts +24 -0
  9. package/dist/api/shared/coop-scheduler.d.ts +60 -0
  10. package/dist/api/shared/coop-scheduler.js +149 -0
  11. package/dist/api/shared/display-adapter.d.ts +2 -2
  12. package/dist/api/shared/display-adapter.js +9 -119
  13. package/dist/api/shared/display-adapters/sdl.js +29 -29
  14. package/dist/api/shared/display-profile.d.ts +38 -33
  15. package/dist/api/shared/display-profile.js +22 -170
  16. package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
  17. package/dist/api/shared/framework-manifest-registry.js +8 -6
  18. package/dist/api/shared/framework-manifest.d.ts +147 -28
  19. package/dist/api/shared/framework-manifest.js +35 -2
  20. package/dist/api/shared/graphics-strategy.d.ts +15 -6
  21. package/dist/api/shared/hal-op-ir.d.ts +340 -3
  22. package/dist/api/shared/hal-op-ir.js +34 -0
  23. package/dist/api/shared/index.d.ts +9 -1
  24. package/dist/api/shared/index.js +11 -1
  25. package/dist/api/shared/ir-core.d.ts +4 -0
  26. package/dist/api/shared/ir-declarations.d.ts +6 -0
  27. package/dist/api/shared/platform-strategy.d.ts +104 -2
  28. package/dist/api/shared/polyfill-helper-registry.js +18 -1
  29. package/dist/api/shared/promise-runtime.d.ts +1 -1
  30. package/dist/api/shared/promise-runtime.js +17 -13
  31. package/dist/api/shared/toolchain-types.d.ts +17 -0
  32. package/dist/api/shared/validate-framework-manifest.js +77 -0
  33. package/dist/api/shared/worker-runtime-polyfill.d.ts +22 -0
  34. package/dist/api/shared/worker-runtime-polyfill.js +34 -0
  35. package/dist/api/shared/worker-runtime.d.ts +69 -0
  36. package/dist/api/shared/worker-runtime.js +163 -0
  37. package/dist/cli.js +125 -121
  38. package/dist/config-loader.d.ts +7 -2
  39. package/dist/config-loader.js +20 -19
  40. package/dist/config-schema.d.ts +107 -65
  41. package/dist/config-schema.js +14 -0
  42. package/dist/contract/board-generator.d.ts +17 -0
  43. package/dist/contract/board-generator.js +57 -0
  44. package/dist/contract/contract-parser.d.ts +217 -0
  45. package/dist/contract/contract-parser.js +224 -0
  46. package/dist/contract/index.d.ts +22 -0
  47. package/dist/contract/index.js +68 -0
  48. package/dist/create/board-codegen.js +4 -4
  49. package/dist/create/board-generators.js +4 -5
  50. package/dist/create/board-spec.d.ts +74 -77
  51. package/dist/create/board-spec.js +0 -1
  52. package/dist/create/init-scaffold.d.ts +7 -3
  53. package/dist/create/init-scaffold.js +0 -62
  54. package/dist/create/init-templates.js +62 -16
  55. package/dist/create/init-wizard.js +32 -27
  56. package/dist/debug/preprocessor.js +178 -39
  57. package/dist/debug/types.d.ts +23 -0
  58. package/dist/diagnostics/mermaid-builder.d.ts +1 -1
  59. package/dist/diagnostics/mermaid-builder.js +34 -24
  60. package/dist/emit/compliance/arxml-writer.d.ts +11 -0
  61. package/dist/emit/compliance/arxml-writer.js +34 -0
  62. package/dist/emit/compliance/compliance-context.d.ts +57 -0
  63. package/dist/emit/compliance/compliance-context.js +113 -0
  64. package/dist/emit/compliance/deviation-ledger.d.ts +27 -0
  65. package/dist/emit/compliance/deviation-ledger.js +47 -0
  66. package/dist/emit/compliance/deviation-writer.d.ts +30 -0
  67. package/dist/emit/compliance/deviation-writer.js +37 -0
  68. package/dist/emit/compliance/index.d.ts +7 -0
  69. package/dist/emit/compliance/index.js +6 -0
  70. package/dist/emit/compliance/rule-engine.d.ts +13 -0
  71. package/dist/emit/compliance/rule-engine.js +101 -0
  72. package/dist/emit/compliance/rules.d.ts +16 -0
  73. package/dist/emit/compliance/rules.js +191 -0
  74. package/dist/emit/compliance/types.d.ts +59 -0
  75. package/dist/emit/compliance/types.js +8 -0
  76. package/dist/emit/emitters/class-emitter.js +6 -1
  77. package/dist/emit/emitters/emitter-context.d.ts +23 -1
  78. package/dist/emit/emitters/function-emitter-impl.js +96 -6
  79. package/dist/emit/emitters/line-appender.js +19 -0
  80. package/dist/emit/emitters/line-marker.d.ts +38 -0
  81. package/dist/emit/emitters/line-marker.js +39 -0
  82. package/dist/emit/emitters/output-finalizer.js +80 -1
  83. package/dist/emit/emitters/setup.d.ts +17 -0
  84. package/dist/emit/emitters/setup.js +217 -36
  85. package/dist/emit/emitters/top-level-prep.js +6 -0
  86. package/dist/emit/emitters/type-decl-emitter.js +28 -3
  87. package/dist/emit/emitters/ui-emitter.js +17 -8
  88. package/dist/emit/expression-renderer.d.ts +1 -1
  89. package/dist/emit/expression-renderer.js +81 -5
  90. package/dist/emit/route-hal-op.js +18 -5
  91. package/dist/emit/snprintf-helpers.js +7 -4
  92. package/dist/emit/statement-renderer.d.ts +10 -0
  93. package/dist/emit/statement-renderer.js +21 -5
  94. package/dist/emit/utils/async-state-machine.js +39 -12
  95. package/dist/framework-package.js +2 -0
  96. package/dist/framework-registry.d.ts +17 -0
  97. package/dist/install/framework-catalog.d.ts +53 -0
  98. package/dist/install/framework-catalog.js +107 -0
  99. package/dist/install/handle-install.d.ts +35 -0
  100. package/dist/install/handle-install.js +177 -0
  101. package/dist/install/index.d.ts +4 -0
  102. package/dist/install/index.js +3 -0
  103. package/dist/ir/adc-range-validation.js +14 -1
  104. package/dist/ir/build-ir-state.d.ts +1 -0
  105. package/dist/ir/build-ir-state.js +14 -0
  106. package/dist/ir/build-ir.js +4 -4
  107. package/dist/ir/call-graph.js +16 -0
  108. package/dist/ir/expression-to-ir.js +150 -0
  109. package/dist/ir/function-builder.js +22 -0
  110. package/dist/ir/hal/hal-emitter.js +10 -6
  111. package/dist/ir/hal/hal-parser.js +16 -9
  112. package/dist/ir/hal/hal-plugins.js +164 -3
  113. package/dist/ir/identifier-collector.js +21 -4
  114. package/dist/ir/interrupt-analysis.d.ts +5 -1
  115. package/dist/ir/interrupt-analysis.js +8 -16
  116. package/dist/ir/ownership-analysis.js +6 -0
  117. package/dist/ir/pin-capability-validation.js +37 -0
  118. package/dist/ir/pin-mode-validation.d.ts +2 -2
  119. package/dist/ir/pin-mode-validation.js +49 -18
  120. package/dist/ir/program-analysis.d.ts +42 -0
  121. package/dist/ir/program-analysis.js +243 -6
  122. package/dist/ir/render-expr.js +11 -0
  123. package/dist/ir/timing-validation.js +11 -2
  124. package/dist/ir/transformers/call-statement.js +105 -0
  125. package/dist/ir/transformers/expressions.js +4 -0
  126. package/dist/ir/transformers/hal-call-resolver.js +21 -0
  127. package/dist/ir/transformers/namespace-methods.js +17 -12
  128. package/dist/ir/transformers/ui-reactive.js +2 -2
  129. package/dist/ir/transformers/variables.js +51 -0
  130. package/dist/ir/type-resolution.js +18 -0
  131. package/dist/ir/ui-element-auto-wire.js +7 -5
  132. package/dist/ir/utils/map-statements.d.ts +4 -0
  133. package/dist/ir/utils/map-statements.js +79 -0
  134. package/dist/ir/validation-orchestrator.js +6 -1
  135. package/dist/ir/worker-analysis.d.ts +10 -0
  136. package/dist/ir/worker-analysis.js +261 -0
  137. package/dist/orchestrator/graph-builder.js +8 -7
  138. package/dist/platform/coop-scheduler-runtime.d.ts +19 -0
  139. package/dist/platform/coop-scheduler-runtime.js +41 -0
  140. package/dist/platform/generic-strategy.d.ts +15 -3
  141. package/dist/platform/generic-strategy.js +49 -4
  142. package/dist/safety/safety-bridge.d.ts +11 -0
  143. package/dist/safety/safety-bridge.js +48 -0
  144. package/dist/safety/sidecar-bridge.d.ts +5 -0
  145. package/dist/safety/sidecar-bridge.js +22 -0
  146. package/dist/safety-hook.d.ts +79 -0
  147. package/dist/safety-hook.js +35 -0
  148. package/dist/stores/display-profile-store.d.ts +0 -1
  149. package/dist/stores/display-profile-store.js +0 -1
  150. package/dist/testing.d.ts +4 -0
  151. package/dist/testing.js +5 -0
  152. package/dist/transpile.js +124 -35
  153. package/dist/types.d.ts +22 -2
  154. package/dist/ui-hook.d.ts +0 -2
  155. package/dist/utils/cli.d.ts +2 -2
  156. package/dist/utils/cli.js +68 -3
  157. package/package.json +20 -5
  158. package/dist/api/shared/display-adapters/eink-mono.d.ts +0 -2
  159. package/dist/api/shared/display-adapters/eink-mono.js +0 -53
  160. package/dist/api/shared/display-adapters/ssd1309.d.ts +0 -2
  161. package/dist/api/shared/display-adapters/ssd1309.js +0 -136
  162. package/dist/api/shared/display-adapters/st7796.d.ts +0 -2
  163. package/dist/api/shared/display-adapters/st7796.js +0 -132
  164. package/dist/libdef/idf-discovery.d.ts +0 -7
  165. package/dist/libdef/idf-discovery.js +0 -59
  166. package/dist/licenses.d.ts +0 -185
  167. package/dist/licenses.js +0 -963
@@ -10,7 +10,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
10
10
  description: z.ZodOptional<z.ZodString>;
11
11
  clockSpeed: z.ZodNumber;
12
12
  fqbn: z.ZodString;
13
- platformioTarget: z.ZodString;
14
13
  arduinoDefine: z.ZodString;
15
14
  moduleFlash: z.ZodNullable<z.ZodNumber>;
16
15
  externalRam: z.ZodNullable<z.ZodNumber>;
@@ -40,7 +39,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
40
39
  }, "strict", z.ZodTypeAny, {
41
40
  gpio: number;
42
41
  capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
43
- notes?: string | undefined;
44
42
  functions?: {
45
43
  type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
46
44
  instance: number;
@@ -49,11 +47,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
49
47
  alt?: string[] | undefined;
50
48
  warnings?: string[] | undefined;
51
49
  unsafe?: boolean | undefined;
50
+ notes?: string | undefined;
52
51
  onboardLed?: boolean | undefined;
53
52
  }, {
54
53
  gpio: number;
55
54
  capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
56
- notes?: string | undefined;
57
55
  functions?: {
58
56
  type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
59
57
  instance: number;
@@ -62,6 +60,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
62
60
  alt?: string[] | undefined;
63
61
  warnings?: string[] | undefined;
64
62
  unsafe?: boolean | undefined;
63
+ notes?: string | undefined;
65
64
  onboardLed?: boolean | undefined;
66
65
  }>, "many">;
67
66
  unsafe: z.ZodArray<z.ZodString, "many">;
@@ -262,11 +261,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
262
261
  channels: z.ZodNumber;
263
262
  pins: z.ZodArray<z.ZodString, "many">;
264
263
  }, "strip", z.ZodTypeAny, {
265
- channels: number;
266
264
  pins: string[];
267
- }, {
268
265
  channels: number;
266
+ }, {
269
267
  pins: string[];
268
+ channels: number;
270
269
  }>>>;
271
270
  timers: z.ZodArray<z.ZodObject<{
272
271
  instance: z.ZodNumber;
@@ -276,12 +275,12 @@ export declare const BoardSpecSchema: z.ZodObject<{
276
275
  }, "strict", z.ZodTypeAny, {
277
276
  type: "general" | "high_speed" | "rtc" | "sys";
278
277
  instance: number;
279
- bits: 16 | 8 | 32 | 64;
278
+ bits: 8 | 16 | 32 | 64;
280
279
  features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
281
280
  }, {
282
281
  type: "general" | "high_speed" | "rtc" | "sys";
283
282
  instance: number;
284
- bits: 16 | 8 | 32 | 64;
283
+ bits: 8 | 16 | 32 | 64;
285
284
  features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
286
285
  }>, "many">;
287
286
  wifi: z.ZodObject<{
@@ -366,6 +365,32 @@ export declare const BoardSpecSchema: z.ZodObject<{
366
365
  }>;
367
366
  }, "strict", z.ZodTypeAny, {
368
367
  architecture: string;
368
+ mcuId: string;
369
+ mcuName: string;
370
+ boardId: string;
371
+ boardName: string;
372
+ vendor: string;
373
+ clockSpeed: number;
374
+ fqbn: string;
375
+ arduinoDefine: string;
376
+ moduleFlash: number | null;
377
+ externalRam: number | null;
378
+ gpioRange: [number, number];
379
+ excludedGpio: number[];
380
+ pins: {
381
+ gpio: number;
382
+ capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
383
+ functions?: {
384
+ type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
385
+ instance: number;
386
+ role: string;
387
+ }[] | undefined;
388
+ alt?: string[] | undefined;
389
+ warnings?: string[] | undefined;
390
+ unsafe?: boolean | undefined;
391
+ notes?: string | undefined;
392
+ onboardLed?: boolean | undefined;
393
+ }[];
369
394
  i2c: Record<string, {
370
395
  sda?: string | undefined;
371
396
  scl?: string | undefined;
@@ -414,39 +439,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
414
439
  vid: string;
415
440
  pid: string;
416
441
  };
417
- wifi: {
418
- type: "wifi" | "wifi6";
419
- supportsStation: boolean;
420
- supportsAp: boolean;
421
- };
422
442
  unsafe: string[];
423
- mcuId: string;
424
- mcuName: string;
425
- boardId: string;
426
- boardName: string;
427
- vendor: string;
428
- clockSpeed: number;
429
- fqbn: string;
430
- platformioTarget: string;
431
- arduinoDefine: string;
432
- moduleFlash: number | null;
433
- externalRam: number | null;
434
- gpioRange: [number, number];
435
- excludedGpio: number[];
436
- pins: {
437
- gpio: number;
438
- capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
439
- notes?: string | undefined;
440
- functions?: {
441
- type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
442
- instance: number;
443
- role: string;
444
- }[] | undefined;
445
- alt?: string[] | undefined;
446
- warnings?: string[] | undefined;
447
- unsafe?: boolean | undefined;
448
- onboardLed?: boolean | undefined;
449
- }[];
450
443
  analog: string[];
451
444
  peripheralInstances: {
452
445
  i2c: {
@@ -468,7 +461,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
468
461
  timers: {
469
462
  type: "general" | "high_speed" | "rtc" | "sys";
470
463
  instance: number;
471
- bits: 16 | 8 | 32 | 64;
464
+ bits: 8 | 16 | 32 | 64;
472
465
  features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
473
466
  }[];
474
467
  features: {
@@ -480,6 +473,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
480
473
  hardwareRng: boolean;
481
474
  fpu: boolean;
482
475
  };
476
+ wifi: {
477
+ type: "wifi" | "wifi6";
478
+ supportsStation: boolean;
479
+ supportsAp: boolean;
480
+ };
483
481
  bluetooth: {
484
482
  type: "classic" | "ble" | "dual";
485
483
  version: string;
@@ -491,13 +489,39 @@ export declare const BoardSpecSchema: z.ZodObject<{
491
489
  externalRam?: number | undefined;
492
490
  rtcMemory?: number | undefined;
493
491
  };
492
+ description?: string | undefined;
494
493
  touch?: {
495
- channels: number;
496
494
  pins: string[];
495
+ channels: number;
497
496
  } | null | undefined;
498
- description?: string | undefined;
499
497
  }, {
500
498
  architecture: string;
499
+ mcuId: string;
500
+ mcuName: string;
501
+ boardId: string;
502
+ boardName: string;
503
+ vendor: string;
504
+ clockSpeed: number;
505
+ fqbn: string;
506
+ arduinoDefine: string;
507
+ moduleFlash: number | null;
508
+ externalRam: number | null;
509
+ gpioRange: [number, number];
510
+ excludedGpio: number[];
511
+ pins: {
512
+ gpio: number;
513
+ capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
514
+ functions?: {
515
+ type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
516
+ instance: number;
517
+ role: string;
518
+ }[] | undefined;
519
+ alt?: string[] | undefined;
520
+ warnings?: string[] | undefined;
521
+ unsafe?: boolean | undefined;
522
+ notes?: string | undefined;
523
+ onboardLed?: boolean | undefined;
524
+ }[];
501
525
  i2c: Record<string, {
502
526
  sda?: string | undefined;
503
527
  scl?: string | undefined;
@@ -546,39 +570,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
546
570
  vid: string;
547
571
  pid: string;
548
572
  };
549
- wifi: {
550
- type: "wifi" | "wifi6";
551
- supportsStation: boolean;
552
- supportsAp: boolean;
553
- };
554
573
  unsafe: string[];
555
- mcuId: string;
556
- mcuName: string;
557
- boardId: string;
558
- boardName: string;
559
- vendor: string;
560
- clockSpeed: number;
561
- fqbn: string;
562
- platformioTarget: string;
563
- arduinoDefine: string;
564
- moduleFlash: number | null;
565
- externalRam: number | null;
566
- gpioRange: [number, number];
567
- excludedGpio: number[];
568
- pins: {
569
- gpio: number;
570
- capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
571
- notes?: string | undefined;
572
- functions?: {
573
- type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
574
- instance: number;
575
- role: string;
576
- }[] | undefined;
577
- alt?: string[] | undefined;
578
- warnings?: string[] | undefined;
579
- unsafe?: boolean | undefined;
580
- onboardLed?: boolean | undefined;
581
- }[];
582
574
  analog: string[];
583
575
  peripheralInstances: {
584
576
  i2c: {
@@ -600,7 +592,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
600
592
  timers: {
601
593
  type: "general" | "high_speed" | "rtc" | "sys";
602
594
  instance: number;
603
- bits: 16 | 8 | 32 | 64;
595
+ bits: 8 | 16 | 32 | 64;
604
596
  features?: ("pwm" | "capture" | "compare" | "interrupt" | "dma")[] | undefined;
605
597
  }[];
606
598
  features: {
@@ -612,6 +604,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
612
604
  hardwareRng: boolean;
613
605
  fpu: boolean;
614
606
  };
607
+ wifi: {
608
+ type: "wifi" | "wifi6";
609
+ supportsStation: boolean;
610
+ supportsAp: boolean;
611
+ };
615
612
  bluetooth: {
616
613
  type: "classic" | "ble" | "dual";
617
614
  version: string;
@@ -623,11 +620,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
623
620
  externalRam?: number | undefined;
624
621
  rtcMemory?: number | undefined;
625
622
  };
623
+ description?: string | undefined;
626
624
  touch?: {
627
- channels: number;
628
625
  pins: string[];
626
+ channels: number;
629
627
  } | null | undefined;
630
- description?: string | undefined;
631
628
  }>;
632
629
  export type BoardSpec = z.infer<typeof BoardSpecSchema>;
633
630
  export declare function parseBoardSpec(jsoncText: string): BoardSpec;
@@ -111,7 +111,6 @@ export const BoardSpecSchema = z.object({
111
111
  // Build
112
112
  clockSpeed: z.number().int(),
113
113
  fqbn: z.string().min(1),
114
- platformioTarget: z.string().min(1),
115
114
  arduinoDefine: z.string().min(1),
116
115
  // Memory (module-level; silicon memory is derived)
117
116
  moduleFlash: z.number().int().nullable(),
@@ -6,12 +6,16 @@ export interface KnownTarget {
6
6
  isNative: boolean;
7
7
  architecture?: ArchitectureIdentifier;
8
8
  boardPackage?: string;
9
- frameworkPackage: string;
10
- framework: string;
9
+ /** Framework package + id. Optional on embedded targets: the scaffold wizard
10
+ * fills these in by discovering installed @typecad/framework-* packages, so
11
+ * KNOWN_TARGETS board entries do not hardcode a framework. Native targets
12
+ * set them directly. */
13
+ frameworkPackage?: string;
14
+ framework?: string;
11
15
  buildTarget?: string;
12
16
  mcu?: string;
13
17
  /** Framework-specific config (becomes frameworkData in cuttlefish.config.ts).
14
- * Used by framework-esp32 to carry `target: 'esp32'|'esp32s3'|'esp32c3'|'esp32c6'`. */
18
+ * Carries framework-specific target/options data for the selected framework. */
15
19
  frameworkData?: Record<string, unknown>;
16
20
  }
17
21
  export declare function registerKnownTarget(target: KnownTarget): void;
@@ -17,8 +17,6 @@ const _knownTargets = [
17
17
  isNative: false,
18
18
  architecture: 'avr',
19
19
  boardPackage: '@typecad/board-arduino-uno',
20
- frameworkPackage: '@typecad/framework-arduino',
21
- framework: 'arduino',
22
20
  buildTarget: 'arduino:avr:uno',
23
21
  mcu: 'atmega328p',
24
22
  },
@@ -28,45 +26,17 @@ const _knownTargets = [
28
26
  isNative: false,
29
27
  architecture: 'esp32',
30
28
  boardPackage: '@typecad/board-esp32-devkit',
31
- frameworkPackage: '@typecad/framework-arduino',
32
- framework: 'arduino',
33
29
  buildTarget: 'esp32:esp32:esp32',
34
30
  mcu: 'esp32',
35
31
  },
36
- {
37
- id: 'esp32-devkit-idf',
38
- displayName: 'ESP32 DevKit (native ESP-IDF)',
39
- isNative: false,
40
- architecture: 'esp32',
41
- boardPackage: '@typecad/board-esp32-devkit',
42
- frameworkPackage: '@typecad/framework-esp32',
43
- framework: 'esp32',
44
- buildTarget: 'esp32:esp32:esp32',
45
- mcu: 'esp32',
46
- frameworkData: { target: 'esp32' },
47
- },
48
32
  {
49
33
  id: 'esp32s3',
50
34
  displayName: 'ESP32-S3',
51
35
  isNative: false,
52
36
  architecture: 'esp32s3',
53
37
  boardPackage: '@typecad/board-esp32s3',
54
- frameworkPackage: '@typecad/framework-arduino',
55
- framework: 'arduino',
56
- buildTarget: 'esp32:esp32:esp32s3',
57
- mcu: 'esp32s3',
58
- },
59
- {
60
- id: 'esp32s3-idf',
61
- displayName: 'ESP32-S3 (native ESP-IDF)',
62
- isNative: false,
63
- architecture: 'esp32s3',
64
- boardPackage: '@typecad/board-esp32s3',
65
- frameworkPackage: '@typecad/framework-esp32',
66
- framework: 'esp32',
67
38
  buildTarget: 'esp32:esp32:esp32s3',
68
39
  mcu: 'esp32s3',
69
- frameworkData: { target: 'esp32s3' },
70
40
  },
71
41
  {
72
42
  id: 'esp32c3',
@@ -74,45 +44,17 @@ const _knownTargets = [
74
44
  isNative: false,
75
45
  architecture: 'esp32c3',
76
46
  boardPackage: '@typecad/board-esp32c3',
77
- frameworkPackage: '@typecad/framework-arduino',
78
- framework: 'arduino',
79
47
  buildTarget: 'esp32:esp32:esp32c3',
80
48
  mcu: 'esp32c3',
81
49
  },
82
- {
83
- id: 'esp32c3-idf',
84
- displayName: 'ESP32-C3 (native ESP-IDF)',
85
- isNative: false,
86
- architecture: 'esp32c3',
87
- boardPackage: '@typecad/board-esp32c3',
88
- frameworkPackage: '@typecad/framework-esp32',
89
- framework: 'esp32',
90
- buildTarget: 'esp32:esp32:esp32c3',
91
- mcu: 'esp32c3',
92
- frameworkData: { target: 'esp32c3' },
93
- },
94
50
  {
95
51
  id: 'esp32c6',
96
52
  displayName: 'ESP32-C6',
97
53
  isNative: false,
98
54
  architecture: 'esp32c6',
99
55
  boardPackage: '@typecad/board-esp32c6',
100
- frameworkPackage: '@typecad/framework-arduino',
101
- framework: 'arduino',
102
- buildTarget: 'esp32:esp32:esp32c6',
103
- mcu: 'esp32c6',
104
- },
105
- {
106
- id: 'esp32c6-idf',
107
- displayName: 'ESP32-C6 (native ESP-IDF)',
108
- isNative: false,
109
- architecture: 'esp32c6',
110
- boardPackage: '@typecad/board-esp32c6',
111
- frameworkPackage: '@typecad/framework-esp32',
112
- framework: 'esp32',
113
56
  buildTarget: 'esp32:esp32:esp32c6',
114
57
  mcu: 'esp32c6',
115
- frameworkData: { target: 'esp32c6' },
116
58
  },
117
59
  {
118
60
  id: 'rp2040',
@@ -120,8 +62,6 @@ const _knownTargets = [
120
62
  isNative: false,
121
63
  architecture: 'rp2040',
122
64
  boardPackage: '@typecad/board-rp2040',
123
- frameworkPackage: '@typecad/framework-arduino',
124
- framework: 'arduino',
125
65
  buildTarget: 'rp2040:rp2040:rpipico',
126
66
  mcu: 'rp2040',
127
67
  },
@@ -131,8 +71,6 @@ const _knownTargets = [
131
71
  isNative: false,
132
72
  architecture: 'rp2350',
133
73
  boardPackage: '@typecad/board-rp2350',
134
- frameworkPackage: '@typecad/framework-arduino',
135
- framework: 'arduino',
136
74
  buildTarget: 'rp2040:rp2040:rpipico2',
137
75
  mcu: 'rp2350',
138
76
  },
@@ -150,24 +150,10 @@ export default config;
150
150
  `;
151
151
  }
152
152
  const buildTarget = options.buildTarget;
153
- const isEspIdf = options.frameworkPackage === '@typecad/framework-esp32'
154
- || options.framework === 'esp32'
155
- || options.toolchainType === 'idf';
156
153
  const resolvedToolchain = options.toolchainType
157
- ?? (isEspIdf ? 'idf' : 'arduino-cli');
158
- // framework-esp32 wants IDF chip ids in frameworkData (target + buildTarget),
159
- // not Arduino FQBNs. Known IDF targets already set frameworkData.target;
160
- // wizard/CLI may still pass an FQBN in buildTarget — normalize to the last segment.
154
+ ?? 'arduino-cli';
161
155
  let frameworkDataBlock = '';
162
- if (isEspIdf) {
163
- const idfTarget = options.frameworkData?.target
164
- ?? options.frameworkData?.buildTarget
165
- ?? (buildTarget?.includes(':') ? buildTarget.split(':').filter(Boolean).pop() : buildTarget)
166
- ?? options.architecture
167
- ?? 'esp32';
168
- frameworkDataBlock = `\n // Framework data (IDF chip target)\n frameworkData: {\n target: '${idfTarget}',\n buildTarget: '${idfTarget}',\n },`;
169
- }
170
- else if (buildTarget) {
156
+ if (buildTarget) {
171
157
  frameworkDataBlock = `\n // Framework data\n frameworkData: {\n buildTarget: '${buildTarget}',\n },`;
172
158
  }
173
159
  const mcuLine = options.mcu
@@ -229,6 +215,22 @@ declare global {
229
215
  type Owned<T = unknown> = T;
230
216
  type Shared<T = unknown> = T;
231
217
  type Mutable<T = unknown> = T;
218
+ // SafeVariable: SEU-resistant storage. The transpiler lowers SafeVariable<number>
219
+ // to a C++ template with inverted-redundancy storage. Declared as an interface
220
+ // (not a type alias) so the TS type checker recognizes method calls.
221
+ // Arithmetic T only (integral or floating-point); string is rejected by a
222
+ // static_assert in the emitted C++ template.
223
+ interface SafeVariable<T = number> { set(value: T): void; get(): T; valid(): boolean; hasFault(): boolean; }
224
+ // SafeInt: chainable bounds-checked signed-integer arithmetic. The transpiler
225
+ // lowers SafeInt<number> to SafeInt<int32_t> (a C++ template with sticky-fault
226
+ // overflow detection). Signed integer T only — unsigned/bool/float/string are
227
+ // rejected by a static_assert in the emitted C++ template.
228
+ interface SafeInt<T = number> {
229
+ add(delta: T): SafeInt<T>; sub(delta: T): SafeInt<T>;
230
+ mul(factor: T): SafeInt<T>; divide(d: T): SafeInt<T>; mod(d: T): SafeInt<T>;
231
+ negate(): SafeInt<T>; absValue(): SafeInt<T>;
232
+ get(): T; hasFault(): boolean; valid(): boolean; reset(newValue: T): void;
233
+ }
232
234
 
233
235
  type uint8_t = number;
234
236
  type int8_t = number;
@@ -254,6 +256,20 @@ declare global {
254
256
  error(...args: unknown[]): void;
255
257
  }
256
258
  const console: Console;
259
+
260
+ // Convenience helper for volatile variables in TypeCAD programs.
261
+ // The transpiler detects calls to volatile() and emits the C++ volatile qualifier.
262
+ declare function volatile<T>(value: T): T;
263
+
264
+ // JS-style timers (declared here so a project does not need "dom" in tsconfig
265
+ // lib to type setInterval/setTimeout). The transpiler rewrites these to
266
+ // __tc_setInterval/__tc_setTimeout and emits the timer_methods polyfill when
267
+ // used. Note: Timing.setInterval/setTimeout (from @typecad/hal) is the
268
+ // preferred single entry point and is typed via the @typecad/board import.
269
+ declare function setInterval(handler: () => void, timeout?: number): number;
270
+ declare function setTimeout(handler: () => void, timeout?: number): number;
271
+ declare function clearInterval(id: number): void;
272
+ declare function clearTimeout(id: number): void;
257
273
  }
258
274
 
259
275
  export {};
@@ -272,6 +288,22 @@ declare global {
272
288
  type Owned<T = unknown> = T;
273
289
  type Shared<T = unknown> = T;
274
290
  type Mutable<T = unknown> = T;
291
+ // SafeVariable: SEU-resistant storage. The transpiler lowers SafeVariable<number>
292
+ // to a C++ template with inverted-redundancy storage. Declared as an interface
293
+ // (not a type alias) so the TS type checker recognizes method calls.
294
+ // Arithmetic T only (integral or floating-point); string is rejected by a
295
+ // static_assert in the emitted C++ template.
296
+ interface SafeVariable<T = number> { set(value: T): void; get(): T; valid(): boolean; hasFault(): boolean; }
297
+ // SafeInt: chainable bounds-checked signed-integer arithmetic. The transpiler
298
+ // lowers SafeInt<number> to SafeInt<int32_t> (a C++ template with sticky-fault
299
+ // overflow detection). Signed integer T only — unsigned/bool/float/string are
300
+ // rejected by a static_assert in the emitted C++ template.
301
+ interface SafeInt<T = number> {
302
+ add(delta: T): SafeInt<T>; sub(delta: T): SafeInt<T>;
303
+ mul(factor: T): SafeInt<T>; divide(d: T): SafeInt<T>; mod(d: T): SafeInt<T>;
304
+ negate(): SafeInt<T>; absValue(): SafeInt<T>;
305
+ get(): T; hasFault(): boolean; valid(): boolean; reset(newValue: T): void;
306
+ }
275
307
 
276
308
  type uint8_t = number;
277
309
  type int8_t = number;
@@ -297,6 +329,20 @@ declare global {
297
329
  error(...args: unknown[]): void;
298
330
  }
299
331
  const console: Console;
332
+
333
+ // Convenience helper for volatile variables in TypeCAD programs.
334
+ // The transpiler detects calls to volatile() and emits the C++ volatile qualifier.
335
+ declare function volatile<T>(value: T): T;
336
+
337
+ // JS-style timers (declared here so a project does not need "dom" in tsconfig
338
+ // lib to type setInterval/setTimeout). The transpiler rewrites these to
339
+ // __tc_setInterval/__tc_setTimeout and emits the timer_methods polyfill when
340
+ // used. Note: Timing.setInterval/setTimeout (from @typecad/hal) is the
341
+ // preferred single entry point and is typed via the @typecad/board import.
342
+ declare function setInterval(handler: () => void, timeout?: number): number;
343
+ declare function setTimeout(handler: () => void, timeout?: number): number;
344
+ declare function clearInterval(id: number): void;
345
+ declare function clearTimeout(id: number): void;
300
346
  }
301
347
 
302
348
  declare module '@typecad/board' {
@@ -84,20 +84,29 @@ export async function runInitWizard(partialOptions) {
84
84
  targetId = await promptSelect(rl, "Target", targetOptions);
85
85
  }
86
86
  const target = KNOWN_TARGETS.find((t) => t.id === targetId);
87
- // 3. Framework (only for embedded targets)
87
+ // 3. Framework (only for embedded targets). Discover installed
88
+ // @typecad/framework-* packages rather than hardcoding a single option, so
89
+ // the wizard reflects whichever frameworks the user has installed.
88
90
  let framework = target.framework;
89
91
  let frameworkPackage = target.frameworkPackage;
90
92
  if (!target.isNative) {
91
- const frameworkOptions = [
92
- { label: "Arduino (digitalWrite, Wire, SPI)", value: 'arduino', pkg: '@typecad/framework-arduino' },
93
+ // Candidate framework families and their user-facing labels. The wizard
94
+ // shows whichever are installed (resolvable) in the user's project.
95
+ const frameworkCandidates = [
96
+ { value: 'arduino', label: 'Arduino (digitalWrite, Wire, SPI)' },
97
+ { value: 'zephyr', label: 'Zephyr RTOS' },
98
+ { value: 'esp-idf', label: 'ESP-IDF' },
93
99
  ];
94
- if (target.architecture === 'avr') {
95
- frameworkOptions.push({ label: "Bare-metal AVR (PORTB, etc.)", value: 'avr', pkg: '@typecad/framework-avr' });
96
- }
97
- // ESP32 family: offer the native ESP-IDF flavor alongside Arduino.
98
- if (target.architecture === 'esp32' || target.architecture === 'esp32s3'
99
- || target.architecture === 'esp32c3' || target.architecture === 'esp32c6') {
100
- frameworkOptions.push({ label: "ESP32 (native ESP-IDF)", value: 'esp32', pkg: '@typecad/framework-esp32' });
100
+ const frameworkOptions = [];
101
+ for (const candidate of frameworkCandidates) {
102
+ const pkg = `@typecad/framework-${candidate.value}`;
103
+ try {
104
+ require.resolve(`${pkg}/package.json`, { paths: [process.cwd()] });
105
+ frameworkOptions.push({ label: candidate.label, value: candidate.value, pkg });
106
+ }
107
+ catch {
108
+ // framework not installed; skip
109
+ }
101
110
  }
102
111
  if (partialOptions?.framework) {
103
112
  const match = frameworkOptions.find(f => f.value === partialOptions.framework);
@@ -105,6 +114,13 @@ export async function runInitWizard(partialOptions) {
105
114
  frameworkPackage = match?.pkg ?? `@typecad/framework-${partialOptions.framework}`;
106
115
  console.log(`${chalk.cyan("?")} Framework: ${chalk.white(framework)}`);
107
116
  }
117
+ else if (frameworkOptions.length === 0) {
118
+ // No framework installed and none requested via --framework: abort
119
+ // rather than produce a broken scaffold with an empty framework field
120
+ // (which would generate invalid package.json + cuttlefish.config.ts).
121
+ throw new Error("No @typecad/framework-* packages found in this project. " +
122
+ "Run 'cuttlefish install' to add one (e.g. 'cuttlefish install arduino').");
123
+ }
108
124
  else if (frameworkOptions.length === 1) {
109
125
  framework = frameworkOptions[0].value;
110
126
  frameworkPackage = frameworkOptions[0].pkg;
@@ -146,10 +162,6 @@ export async function runInitWizard(partialOptions) {
146
162
  else {
147
163
  includeSketch = await promptConfirm(rl, "Create starter sketch?", true);
148
164
  }
149
- const isEspIdf = frameworkPackage === '@typecad/framework-esp32' || framework === 'esp32';
150
- const idfTarget = target.frameworkData?.target
151
- ?? target.architecture
152
- ?? 'esp32';
153
165
  return {
154
166
  projectName,
155
167
  targetId: target.id,
@@ -157,22 +169,15 @@ export async function runInitWizard(partialOptions) {
157
169
  isNative: target.isNative,
158
170
  architecture: target.architecture,
159
171
  boardPackage: target.boardPackage,
160
- frameworkPackage,
161
- framework,
162
- buildTarget: isEspIdf ? idfTarget : target.buildTarget,
172
+ frameworkPackage: frameworkPackage ?? '',
173
+ framework: framework ?? '',
174
+ buildTarget: target.buildTarget,
163
175
  mcu: target.mcu,
164
176
  baudRate,
165
177
  includeSketch,
166
- ...(isEspIdf
167
- ? {
168
- toolchainType: 'idf',
169
- frameworkData: target.frameworkData?.target
170
- ? { ...target.frameworkData }
171
- : { target: idfTarget, buildTarget: idfTarget },
172
- }
173
- : target.frameworkData
174
- ? { frameworkData: target.frameworkData }
175
- : {}),
178
+ ...(target.frameworkData
179
+ ? { frameworkData: target.frameworkData }
180
+ : {}),
176
181
  };
177
182
  }
178
183
  catch (err) {