@typecad/cuttlefish 1.0.0-alpha.11 → 1.0.0-alpha.13

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 (65) hide show
  1. package/dist/add-preset.d.ts +4 -0
  2. package/dist/add-preset.js +74 -0
  3. package/dist/api/config.d.ts +5 -5
  4. package/dist/api/shared/display-adapters/sdl.js +1 -1
  5. package/dist/api/shared/display-profile.d.ts +11 -0
  6. package/dist/api/shared/display-profile.js +3 -0
  7. package/dist/api/shared/framework-manifest.d.ts +85 -78
  8. package/dist/api/shared/framework-manifest.js +1 -0
  9. package/dist/api/shared/hal-op-ir.d.ts +19 -0
  10. package/dist/api/shared/toolchain-types.d.ts +0 -1
  11. package/dist/cli.js +21 -4
  12. package/dist/config-loader.d.ts +8 -2
  13. package/dist/config-loader.js +202 -53
  14. package/dist/config-schema.d.ts +7 -7
  15. package/dist/config-schema.js +3 -3
  16. package/dist/create/board-spec.d.ts +122 -122
  17. package/dist/create/debug-artifacts.d.ts +20 -0
  18. package/dist/create/debug-artifacts.js +69 -0
  19. package/dist/create/eslint-rules-template.js +6 -3
  20. package/dist/create/index.d.ts +2 -0
  21. package/dist/create/index.js +1 -0
  22. package/dist/create/init-scaffold.d.ts +1 -0
  23. package/dist/create/init-scaffold.js +5 -0
  24. package/dist/create/init-templates.js +0 -2
  25. package/dist/emit/compliance/rules.js +52 -4
  26. package/dist/emit/emitters/function-emitter-impl.js +7 -1
  27. package/dist/emit/emitters/line-appender.js +6 -0
  28. package/dist/emit/emitters/setup.js +15 -2
  29. package/dist/emit/emitters/ui-emitter.js +40 -15
  30. package/dist/emit/route-hal-op.js +55 -1
  31. package/dist/emit/statement-renderer.js +5 -2
  32. package/dist/ir/build-ir.js +22 -1
  33. package/dist/ir/expression-to-ir.js +17 -0
  34. package/dist/ir/feature-registry.js +22 -6
  35. package/dist/ir/hal/hal-emitter.js +23 -5
  36. package/dist/ir/hal/hal-plugins.js +11 -0
  37. package/dist/ir/pin-mode-validation.js +32 -9
  38. package/dist/ir/pin-state-tracking.d.ts +58 -0
  39. package/dist/ir/pin-state-tracking.js +182 -0
  40. package/dist/ir/program-analysis.d.ts +10 -2
  41. package/dist/ir/program-analysis.js +40 -4
  42. package/dist/ir/statement-to-ir.js +14 -0
  43. package/dist/ir/transformers/control-flow.js +29 -0
  44. package/dist/ir/transformers/ui-call-resolver.js +105 -1
  45. package/dist/ir/ui-element-auto-wire.js +7 -4
  46. package/dist/orchestrator/graph-builder.d.ts +4 -1
  47. package/dist/orchestrator/graph-builder.js +7 -1
  48. package/dist/platform/async-runtime.d.ts +1 -1
  49. package/dist/platform/async-runtime.js +12 -3
  50. package/dist/platform/generic-strategy.js +1 -1
  51. package/dist/preview/api-shared-shim.d.ts +1 -0
  52. package/dist/preview/api-shared-shim.js +7 -0
  53. package/dist/preview/client.js +220 -1
  54. package/dist/preview/server.js +154 -62
  55. package/dist/theme-tokens.d.ts +22 -0
  56. package/dist/theme-tokens.js +172 -0
  57. package/dist/transpile.js +90 -12
  58. package/dist/types.d.ts +5 -0
  59. package/dist/ui-hook.d.ts +7 -0
  60. package/dist/utils/cli.js +9 -0
  61. package/dist/utils/fs.d.ts +2 -0
  62. package/dist/utils/fs.js +16 -0
  63. package/dist/utils/ui.d.ts +5 -0
  64. package/dist/utils/ui.js +7 -0
  65. package/package.json +7 -5
@@ -0,0 +1,4 @@
1
+ import type { AddCommandOptions } from "./types.js";
2
+ export declare function listAddPresets(): string;
3
+ /** Run `cuttlefish add <preset>`: copy the preset into the project. */
4
+ export declare function runAddPreset(options: AddCommandOptions): void;
@@ -0,0 +1,74 @@
1
+ // ---------------------------------------------------------------------------
2
+ // `cuttlefish add <preset>` — scaffold copy-and-own assets into a project.
3
+ //
4
+ // Presets are files shipped with the package under assets/. The command COPIES
5
+ // them into the user's project (never injected at build time): the user owns
6
+ // the file from day one and the build only reads what they reference. This is
7
+ // the same philosophy as shadcn/ui — components as source you keep, not a
8
+ // runtime dependency.
9
+ // ---------------------------------------------------------------------------
10
+ import fs from "node:fs";
11
+ import path from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+ import { loadShadcnTheme, applyShadcnTheme } from "./theme-tokens.js";
14
+ import chalk from "chalk";
15
+ const ASSETS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../assets");
16
+ const PRESETS = {
17
+ shadcn: {
18
+ source: "shadcn/shadcn.css",
19
+ dest: "src/styles/shadcn.css",
20
+ description: "shadcn-style CSS variable tokens + component class recipes (buttons, cards, badges, alerts, ...)",
21
+ nextSteps: [
22
+ `Link it from a stylesheet (sibling .ui.css file or a <style> block):`,
23
+ ``,
24
+ ` @import "./styles/shadcn.css";`,
25
+ ``,
26
+ `Then use the classes on native elements:`,
27
+ ` <button class="btn btn-primary">Save</button>`,
28
+ ` <view class="card"> ... <text class="card-title">Title</text> ... </view>`,
29
+ ``,
30
+ `Dark theme: the file defines a .dark token set — activate it with`,
31
+ `themeClass: 'dark' in cuttlefish.config.ts's display block.`,
32
+ `The file is yours: tune tokens and prune recipes freely.`,
33
+ ``,
34
+ `Themes: start from an included one with --theme <name>`,
35
+ `(see \`cuttlefish theme\` for the list); swap later with the same command.`,
36
+ ],
37
+ },
38
+ };
39
+ export function listAddPresets() {
40
+ return Object.entries(PRESETS).map(([id, p]) => ` ${id.padEnd(10)} ${p.description}`).join("\n");
41
+ }
42
+ /** Run `cuttlefish add <preset>`: copy the preset into the project. */
43
+ export function runAddPreset(options) {
44
+ const preset = PRESETS[options.preset];
45
+ if (!preset) {
46
+ throw new Error(`Unknown preset "${options.preset}". Available presets:\n${listAddPresets()}`);
47
+ }
48
+ const src = path.join(ASSETS_DIR, preset.source);
49
+ if (!fs.existsSync(src)) {
50
+ throw new Error(`Preset asset missing from the cuttlefish package: ${src}`);
51
+ }
52
+ const dest = path.resolve(options.projectRoot, preset.dest);
53
+ if (fs.existsSync(dest) && !options.force) {
54
+ throw new Error(`${dest} already exists — re-run with --force to overwrite (your edits will be lost).`);
55
+ }
56
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
57
+ fs.copyFileSync(src, dest);
58
+ // --theme <name>: merge an included shadcn theme's tokens into the copied
59
+ // stylesheet (shadcn preset only; no-op for future presets without themes).
60
+ if (options.theme) {
61
+ if (options.preset !== "shadcn") {
62
+ throw new Error(`--theme applies to the shadcn preset only (got "${options.preset}").`);
63
+ }
64
+ const theme = loadShadcnTheme(options.theme, options.projectRoot);
65
+ fs.writeFileSync(dest, applyShadcnTheme(fs.readFileSync(dest, "utf-8"), theme), "utf-8");
66
+ console.log(chalk.green(`✓`) + ` Theme ${chalk.cyan(theme.name)} tokens merged into the copied file.`);
67
+ }
68
+ console.log(chalk.green(`✓`) + ` Added preset ${chalk.cyan(options.preset)} → ${path.relative(options.projectRoot, dest)}`);
69
+ console.log();
70
+ console.log(chalk.bold(`Next steps:`));
71
+ for (const line of preset.nextSteps) {
72
+ console.log(line ? ` ${line}` : ``);
73
+ }
74
+ }
@@ -2,8 +2,6 @@ import type { ArchitectureIdentifier } from './board-types.js';
2
2
  import type { DisplayConfig } from './shared/display-profile.js';
3
3
  /** Build-system / framework the transpiler should target. */
4
4
  type OutputFramework = string & {};
5
- /** Optimization strategy. */
6
- type OptimizationLevel = 'none' | 'size' | 'speed' | 'balanced';
7
5
  /**
8
6
  * Output section — controls how generated C++ is laid out.
9
7
  */
@@ -14,8 +12,6 @@ interface CuttlefishOutputConfig {
14
12
  * Matches the optional Zod `output.framework` in config-schema.ts.
15
13
  */
16
14
  framework?: OutputFramework;
17
- /** Optimization level. */
18
- optimize?: OptimizationLevel;
19
15
  /** Directory to write generated files into (relative to project root). */
20
16
  outDir?: string;
21
17
  /** Additional compiler defines (KEY = value). */
@@ -54,8 +50,12 @@ export interface CuttlefishConfig {
54
50
  /**
55
51
  * MCU package providing silicon definitions.
56
52
  * Example: '@typecad/mcu-atmega328p'
53
+ *
54
+ * Optional for native/host targets — a desktop build has no MCU (the
55
+ * loader generates a boardless `@typecad/board` shim). Embedded targets
56
+ * should set this (or the deprecated `board`).
57
57
  */
58
- mcu: string;
58
+ mcu?: string;
59
59
  /**
60
60
  * Board package to use. (Deprecated — use mcu + contract instead)
61
61
  */
@@ -323,7 +323,7 @@ export const sdlAdapter = (display) => {
323
323
  ` __tc_display.put(dx, dy, pixels[i]);`,
324
324
  ` }`,
325
325
  `}`,
326
- `static inline CuttlefishCanvas16* display_createCanvas(int16_t w, int16_t h) { return new SdlGfxCanvas(w, h); }`,
326
+ `static inline CuttlefishCanvas16* display_createCanvas(int16_t w, int16_t h) { return new (std::nothrow) SdlGfxCanvas(w, h); }`,
327
327
  `static inline CuttlefishCanvas16* display_createCanvasPsram(int16_t, int16_t) { return nullptr; }`,
328
328
  `static inline void display_deleteCanvas(CuttlefishCanvas16* c) { delete c; }`,
329
329
  `static inline int16_t display_canvasWidth(CuttlefishCanvas16* c) { return c->width(); }`,
@@ -86,6 +86,11 @@ export interface DisplayProfile {
86
86
  * is read, so a missing/unsafe readback path must not affect normal drawing.
87
87
  */
88
88
  scanlineSync?: boolean;
89
+ /** Tearing-effect (TE) sync, hardware variant: GPIO number of the panel's
90
+ * TE output. Opt-in — few off-the-shelf display boards break the pin out.
91
+ * When wired, panel updates wait for the TE frame pulse instead of the
92
+ * GET_SCANLINE readback (no MISO needed; see also scanlineSync). */
93
+ tearingEffectPin?: number;
89
94
  touch?: TouchProfile;
90
95
  /** Enable antialiased rendering for circles, lines, rounded corners, and text
91
96
  * unless a node opts out with font-smoothing:none.
@@ -158,6 +163,12 @@ export interface DisplayConfig {
158
163
  * default because some ST7796S modules misbehave when this command is read.
159
164
  */
160
165
  scanlineSync?: boolean;
166
+ /** Tearing-effect (TE) hardware sync: GPIO number of the panel's TE output
167
+ * (ST7796S TE / ILI9341 TE pin). Strictly opt-in — few off-the-shelf
168
+ * display boards break the pin out. When wired, panel updates arm on the
169
+ * TE frame pulse (tear-free writes, no MISO readback); the Zephyr overlay
170
+ * emits te-gpios on the display DT node and the adapter raises TEON. */
171
+ tearingEffectPin?: number;
161
172
  touch?: TouchProfile | false;
162
173
  cs?: number;
163
174
  dc?: number;
@@ -81,6 +81,7 @@ export function resolveDisplayProfile(config, registry) {
81
81
  spiPins: config.spiPins,
82
82
  colorOrder: config.colorOrder,
83
83
  invertDisplay: config.invertDisplay,
84
+ tearingEffectPin: config.tearingEffectPin,
84
85
  touch: config.touch === false ? undefined : config.touch,
85
86
  displayClass: config.displayClass,
86
87
  capabilities: config.capabilities,
@@ -112,6 +113,8 @@ export function resolveDisplayProfile(config, registry) {
112
113
  base.colorOrder = config.colorOrder;
113
114
  if (config.invertDisplay !== undefined)
114
115
  base.invertDisplay = config.invertDisplay;
116
+ if (config.tearingEffectPin !== undefined)
117
+ base.tearingEffectPin = config.tearingEffectPin;
115
118
  if (config.scanlineSync !== undefined)
116
119
  base.scanlineSync = config.scanlineSync;
117
120
  if (config.touch === false)
@@ -20,17 +20,17 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
20
20
  generateHeaderFile: z.ZodBoolean;
21
21
  customBridgeShim: z.ZodOptional<z.ZodString>;
22
22
  }, "strip", z.ZodTypeAny, {
23
+ sourceExtension: "cpp" | "ino" | "cc" | "h";
23
24
  entrypointFunctionName: string;
24
25
  requiresLoopFunction: boolean;
25
- sourceExtension: "ino" | "cc" | "cpp" | "h";
26
26
  generateHeaderFile: boolean;
27
27
  overrideBaseName?: string | undefined;
28
28
  outputSubdirectory?: string | undefined;
29
29
  customBridgeShim?: string | undefined;
30
30
  }, {
31
+ sourceExtension: "cpp" | "ino" | "cc" | "h";
31
32
  entrypointFunctionName: string;
32
33
  requiresLoopFunction: boolean;
33
- sourceExtension: "ino" | "cc" | "cpp" | "h";
34
34
  generateHeaderFile: boolean;
35
35
  overrideBaseName?: string | undefined;
36
36
  outputSubdirectory?: string | undefined;
@@ -41,13 +41,13 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
41
41
  forcedIncludes: z.ZodArray<z.ZodString, "many">;
42
42
  symbolAliases: z.ZodRecord<z.ZodString, z.ZodString>;
43
43
  }, "strip", z.ZodTypeAny, {
44
- targets: string[];
45
44
  forcedIncludes: string[];
46
45
  symbolAliases: Record<string, string>;
47
- }, {
48
46
  targets: string[];
47
+ }, {
49
48
  forcedIncludes: string[];
50
49
  symbolAliases: Record<string, string>;
50
+ targets: string[];
51
51
  }>;
52
52
  hal: z.ZodObject<{
53
53
  [x: string]: z.ZodObject<{
@@ -57,12 +57,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
57
57
  partialCoverage: z.ZodDefault<z.ZodBoolean>;
58
58
  }, "strip", z.ZodTypeAny, {
59
59
  supported: boolean;
60
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
60
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
61
61
  partialCoverage: boolean;
62
62
  unsupportedReason?: string | undefined;
63
63
  }, {
64
64
  supported: boolean;
65
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
65
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
66
66
  unsupportedReason?: string | undefined;
67
67
  partialCoverage?: boolean | undefined;
68
68
  }>;
@@ -81,12 +81,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
81
81
  partialCoverage: z.ZodDefault<z.ZodBoolean>;
82
82
  }, "strip", z.ZodTypeAny, {
83
83
  supported: boolean;
84
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
84
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
85
85
  partialCoverage: boolean;
86
86
  unsupportedReason?: string | undefined;
87
87
  }, {
88
88
  supported: boolean;
89
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
89
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
90
90
  unsupportedReason?: string | undefined;
91
91
  partialCoverage?: boolean | undefined;
92
92
  }>, z.objectOutputType<{
@@ -97,12 +97,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
97
97
  partialCoverage: z.ZodDefault<z.ZodBoolean>;
98
98
  }, "strip", z.ZodTypeAny, {
99
99
  supported: boolean;
100
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
100
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
101
101
  partialCoverage: boolean;
102
102
  unsupportedReason?: string | undefined;
103
103
  }, {
104
104
  supported: boolean;
105
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
105
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
106
106
  unsupportedReason?: string | undefined;
107
107
  partialCoverage?: boolean | undefined;
108
108
  }>;
@@ -121,12 +121,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
121
121
  partialCoverage: z.ZodDefault<z.ZodBoolean>;
122
122
  }, "strip", z.ZodTypeAny, {
123
123
  supported: boolean;
124
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
124
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
125
125
  partialCoverage: boolean;
126
126
  unsupportedReason?: string | undefined;
127
127
  }, {
128
128
  supported: boolean;
129
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
129
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
130
130
  unsupportedReason?: string | undefined;
131
131
  partialCoverage?: boolean | undefined;
132
132
  }>, "strip">, z.objectInputType<{
@@ -137,12 +137,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
137
137
  partialCoverage: z.ZodDefault<z.ZodBoolean>;
138
138
  }, "strip", z.ZodTypeAny, {
139
139
  supported: boolean;
140
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
140
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
141
141
  partialCoverage: boolean;
142
142
  unsupportedReason?: string | undefined;
143
143
  }, {
144
144
  supported: boolean;
145
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
145
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
146
146
  unsupportedReason?: string | undefined;
147
147
  partialCoverage?: boolean | undefined;
148
148
  }>;
@@ -161,12 +161,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
161
161
  partialCoverage: z.ZodDefault<z.ZodBoolean>;
162
162
  }, "strip", z.ZodTypeAny, {
163
163
  supported: boolean;
164
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
164
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
165
165
  partialCoverage: boolean;
166
166
  unsupportedReason?: string | undefined;
167
167
  }, {
168
168
  supported: boolean;
169
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
169
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
170
170
  unsupportedReason?: string | undefined;
171
171
  partialCoverage?: boolean | undefined;
172
172
  }>, "strip">>;
@@ -222,16 +222,19 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
222
222
  compile: z.ZodBoolean;
223
223
  upload: z.ZodBoolean;
224
224
  monitor: z.ZodBoolean;
225
+ debug: z.ZodOptional<z.ZodBoolean>;
225
226
  }, "strip", z.ZodTypeAny, {
226
227
  prepare: boolean;
227
228
  compile: boolean;
228
229
  upload: boolean;
229
230
  monitor: boolean;
231
+ debug?: boolean | undefined;
230
232
  }, {
231
233
  prepare: boolean;
232
234
  compile: boolean;
233
235
  upload: boolean;
234
236
  monitor: boolean;
237
+ debug?: boolean | undefined;
235
238
  }>;
236
239
  reexportedFrom: z.ZodOptional<z.ZodString>;
237
240
  }, "strip", z.ZodTypeAny, {
@@ -241,6 +244,7 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
241
244
  compile: boolean;
242
245
  upload: boolean;
243
246
  monitor: boolean;
247
+ debug?: boolean | undefined;
244
248
  };
245
249
  reexportedFrom?: string | undefined;
246
250
  }, {
@@ -250,6 +254,7 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
250
254
  compile: boolean;
251
255
  upload: boolean;
252
256
  monitor: boolean;
257
+ debug?: boolean | undefined;
253
258
  };
254
259
  reexportedFrom?: string | undefined;
255
260
  }>;
@@ -305,12 +310,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
305
310
  recommendedStringImpl: "std_string" | "static_string";
306
311
  }>;
307
312
  }, "strip", z.ZodTypeAny, {
308
- normalizeCppType: boolean;
309
- mathHeader: "none" | "<math.h>" | "<Arduino.h>";
313
+ needsIostream: boolean;
310
314
  needsStdString: boolean;
311
315
  needsStdVector: boolean;
312
- needsIostream: boolean;
313
316
  needsStdFunction: boolean;
317
+ mathHeader: "none" | "<math.h>" | "<Arduino.h>";
318
+ normalizeCppType: boolean;
314
319
  stdlibSupport: {
315
320
  hasVector: boolean;
316
321
  hasString: boolean;
@@ -321,12 +326,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
321
326
  recommendedStringImpl: "std_string" | "static_string";
322
327
  };
323
328
  }, {
324
- normalizeCppType: boolean;
325
- mathHeader: "none" | "<math.h>" | "<Arduino.h>";
329
+ needsIostream: boolean;
326
330
  needsStdString: boolean;
327
331
  needsStdVector: boolean;
328
- needsIostream: boolean;
329
332
  needsStdFunction: boolean;
333
+ mathHeader: "none" | "<math.h>" | "<Arduino.h>";
334
+ normalizeCppType: boolean;
330
335
  stdlibSupport: {
331
336
  hasVector: boolean;
332
337
  hasString: boolean;
@@ -371,42 +376,42 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
371
376
  zephyr?: string | undefined;
372
377
  }>>;
373
378
  }, "strip", z.ZodTypeAny, {
379
+ hal: {
380
+ [x: string]: {
381
+ supported: boolean;
382
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
383
+ partialCoverage: boolean;
384
+ unsupportedReason?: string | undefined;
385
+ };
386
+ raw?: unknown;
387
+ } & {
388
+ [k: string]: {
389
+ supported: boolean;
390
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
391
+ partialCoverage: boolean;
392
+ unsupportedReason?: string | undefined;
393
+ };
394
+ };
395
+ packageName: string;
374
396
  schemaVersion: 1;
375
397
  frameworkId: string;
376
- packageName: string;
377
398
  canonical: boolean;
378
399
  displayName: string;
379
400
  description: string;
380
401
  implementationMode: "from-scratch" | "extends-canonical" | "extends-other";
381
402
  entrypoint: {
403
+ sourceExtension: "cpp" | "ino" | "cc" | "h";
382
404
  entrypointFunctionName: string;
383
405
  requiresLoopFunction: boolean;
384
- sourceExtension: "ino" | "cc" | "cpp" | "h";
385
406
  generateHeaderFile: boolean;
386
407
  overrideBaseName?: string | undefined;
387
408
  outputSubdirectory?: string | undefined;
388
409
  customBridgeShim?: string | undefined;
389
410
  };
390
411
  profile: {
391
- targets: string[];
392
412
  forcedIncludes: string[];
393
413
  symbolAliases: Record<string, string>;
394
- };
395
- hal: {
396
- [x: string]: {
397
- supported: boolean;
398
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
399
- partialCoverage: boolean;
400
- unsupportedReason?: string | undefined;
401
- };
402
- raw?: unknown;
403
- } & {
404
- [k: string]: {
405
- supported: boolean;
406
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
407
- partialCoverage: boolean;
408
- unsupportedReason?: string | undefined;
409
- };
414
+ targets: string[];
410
415
  };
411
416
  polyfills: {
412
417
  emitted: {
@@ -426,16 +431,17 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
426
431
  compile: boolean;
427
432
  upload: boolean;
428
433
  monitor: boolean;
434
+ debug?: boolean | undefined;
429
435
  };
430
436
  reexportedFrom?: string | undefined;
431
437
  };
432
438
  typeEmission: {
433
- normalizeCppType: boolean;
434
- mathHeader: "none" | "<math.h>" | "<Arduino.h>";
439
+ needsIostream: boolean;
435
440
  needsStdString: boolean;
436
441
  needsStdVector: boolean;
437
- needsIostream: boolean;
438
442
  needsStdFunction: boolean;
443
+ mathHeader: "none" | "<math.h>" | "<Arduino.h>";
444
+ normalizeCppType: boolean;
439
445
  stdlibSupport: {
440
446
  hasVector: boolean;
441
447
  hasString: boolean;
@@ -451,6 +457,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
451
457
  hardwareTestGroups: string[];
452
458
  halResolutionTests: string[];
453
459
  };
460
+ doctor?: {
461
+ available: boolean;
462
+ } | undefined;
463
+ licenses?: {
464
+ available: boolean;
465
+ } | undefined;
454
466
  basedOn?: string | undefined;
455
467
  inheritsStrategyId?: string | undefined;
456
468
  libraryResolution?: {
@@ -460,51 +472,45 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
460
472
  tryGenerateLibDecl: boolean;
461
473
  reexportedFrom?: string | undefined;
462
474
  } | undefined;
463
- doctor?: {
464
- available: boolean;
465
- } | undefined;
466
- licenses?: {
467
- available: boolean;
468
- } | undefined;
469
475
  compat?: {
470
476
  zephyr?: string | undefined;
471
477
  } | undefined;
472
478
  }, {
479
+ hal: {
480
+ [x: string]: {
481
+ supported: boolean;
482
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
483
+ unsupportedReason?: string | undefined;
484
+ partialCoverage?: boolean | undefined;
485
+ };
486
+ raw?: unknown;
487
+ } & {
488
+ [k: string]: {
489
+ supported: boolean;
490
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
491
+ unsupportedReason?: string | undefined;
492
+ partialCoverage?: boolean | undefined;
493
+ };
494
+ };
495
+ packageName: string;
473
496
  schemaVersion: 1;
474
497
  frameworkId: string;
475
- packageName: string;
476
498
  displayName: string;
477
499
  description: string;
478
500
  implementationMode: "from-scratch" | "extends-canonical" | "extends-other";
479
501
  entrypoint: {
502
+ sourceExtension: "cpp" | "ino" | "cc" | "h";
480
503
  entrypointFunctionName: string;
481
504
  requiresLoopFunction: boolean;
482
- sourceExtension: "ino" | "cc" | "cpp" | "h";
483
505
  generateHeaderFile: boolean;
484
506
  overrideBaseName?: string | undefined;
485
507
  outputSubdirectory?: string | undefined;
486
508
  customBridgeShim?: string | undefined;
487
509
  };
488
510
  profile: {
489
- targets: string[];
490
511
  forcedIncludes: string[];
491
512
  symbolAliases: Record<string, string>;
492
- };
493
- hal: {
494
- [x: string]: {
495
- supported: boolean;
496
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
497
- unsupportedReason?: string | undefined;
498
- partialCoverage?: boolean | undefined;
499
- };
500
- raw?: unknown;
501
- } & {
502
- [k: string]: {
503
- supported: boolean;
504
- ops: Record<string, "supported" | "stub" | "unsupported" | "probe-inconclusive" | "polyfill">;
505
- unsupportedReason?: string | undefined;
506
- partialCoverage?: boolean | undefined;
507
- };
513
+ targets: string[];
508
514
  };
509
515
  polyfills: {
510
516
  emitted: {
@@ -524,16 +530,17 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
524
530
  compile: boolean;
525
531
  upload: boolean;
526
532
  monitor: boolean;
533
+ debug?: boolean | undefined;
527
534
  };
528
535
  reexportedFrom?: string | undefined;
529
536
  };
530
537
  typeEmission: {
531
- normalizeCppType: boolean;
532
- mathHeader: "none" | "<math.h>" | "<Arduino.h>";
538
+ needsIostream: boolean;
533
539
  needsStdString: boolean;
534
540
  needsStdVector: boolean;
535
- needsIostream: boolean;
536
541
  needsStdFunction: boolean;
542
+ mathHeader: "none" | "<math.h>" | "<Arduino.h>";
543
+ normalizeCppType: boolean;
537
544
  stdlibSupport: {
538
545
  hasVector: boolean;
539
546
  hasString: boolean;
@@ -549,6 +556,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
549
556
  hardwareTestGroups: string[];
550
557
  halResolutionTests: string[];
551
558
  };
559
+ doctor?: {
560
+ available: boolean;
561
+ } | undefined;
562
+ licenses?: {
563
+ available: boolean;
564
+ } | undefined;
552
565
  canonical?: boolean | undefined;
553
566
  basedOn?: string | undefined;
554
567
  inheritsStrategyId?: string | undefined;
@@ -559,12 +572,6 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
559
572
  tryGenerateLibDecl: boolean;
560
573
  reexportedFrom?: string | undefined;
561
574
  } | undefined;
562
- doctor?: {
563
- available: boolean;
564
- } | undefined;
565
- licenses?: {
566
- available: boolean;
567
- } | undefined;
568
575
  compat?: {
569
576
  zephyr?: string | undefined;
570
577
  } | undefined;
@@ -84,6 +84,7 @@ const ToolchainCoverageSchema = z.object({
84
84
  compile: z.boolean(),
85
85
  upload: z.boolean(),
86
86
  monitor: z.boolean(),
87
+ debug: z.boolean().optional(),
87
88
  }),
88
89
  reexportedFrom: z.string().optional(),
89
90
  });
@@ -7,16 +7,35 @@ export interface GpioWriteOp {
7
7
  pin: number;
8
8
  /** 0 = LOW, 1 = HIGH, or a runtime expression string (e.g. "state", "!state") */
9
9
  value: 0 | 1 | string;
10
+ /**
11
+ * Output-pin state tracking: set at the END of the file's IR build (see
12
+ * markShadowUpdatingOps) when this pin has a tracked shadow read anywhere
13
+ * in the file — the emitted write must also assign the shadow state
14
+ * variable. Baked into the op at build time because emit never sees live
15
+ * tracker state: every file's buildProgramIR resets the tracker, and all
16
+ * files build before any emit runs.
17
+ */
18
+ updatesShadow?: boolean;
10
19
  }
11
20
  export interface GpioReadOp {
12
21
  operation: "gpio.read";
13
22
  port?: string;
14
23
  pin: number;
24
+ /**
25
+ * Output-pin state tracking: when set, this read is on a pin explicitly
26
+ * configured as OUTPUT and must NOT lower to a hardware pin read (which is
27
+ * not portable for direction-only outputs, e.g. Zephyr). 'high'/'low' fold
28
+ * to a compile-time constant; 'shadow' lowers to the tracked state
29
+ * variable that generated writes keep updated.
30
+ */
31
+ trackedValue?: "high" | "low" | "shadow";
15
32
  }
16
33
  export interface GpioToggleOp {
17
34
  operation: "gpio.toggle";
18
35
  port?: string;
19
36
  pin: number;
37
+ /** Output-pin state tracking — same contract as GpioWriteOp.updatesShadow. */
38
+ updatesShadow?: boolean;
20
39
  }
21
40
  export interface GpioSetModeOp {
22
41
  operation: "gpio.set_mode";
@@ -28,7 +28,6 @@ export interface ToolchainOptions {
28
28
  buildTarget?: string;
29
29
  port?: string;
30
30
  baud?: number;
31
- optimize?: string;
32
31
  extraFlags?: string[];
33
32
  defines?: Record<string, string>;
34
33
  /** ESP32 PSRAM type ('opi' | 'quad') when the target board has PSRAM. */