@typecad/cuttlefish 1.0.0-alpha.12 → 1.0.0-alpha.14

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 (101) hide show
  1. package/assets/editor-extensions/typecad-debug/README.md +142 -0
  2. package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
  3. package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
  4. package/assets/editor-extensions/typecad-debug/package.json +76 -0
  5. package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
  6. package/assets/editor-extensions/typecad-ui/README.md +52 -0
  7. package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
  8. package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
  9. package/assets/editor-extensions/typecad-ui/icon.png +0 -0
  10. package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
  11. package/assets/editor-extensions/typecad-ui/package.json +54 -0
  12. package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
  13. package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
  14. package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
  15. package/dist/add-preset.d.ts +4 -0
  16. package/dist/add-preset.js +74 -0
  17. package/dist/api/config.d.ts +8 -5
  18. package/dist/api/shared/display-adapters/sdl.js +1 -1
  19. package/dist/api/shared/display-profile.d.ts +11 -0
  20. package/dist/api/shared/display-profile.js +3 -0
  21. package/dist/api/shared/framework-manifest.d.ts +61 -504
  22. package/dist/api/shared/hal-op-ir.d.ts +19 -0
  23. package/dist/api/shared/toolchain-types.d.ts +0 -1
  24. package/dist/cli.js +31 -9
  25. package/dist/config-loader.d.ts +0 -2
  26. package/dist/config-loader.js +13 -6
  27. package/dist/config-schema.d.ts +17 -230
  28. package/dist/config-schema.js +1 -3
  29. package/dist/contract/contract-parser.d.ts +9 -127
  30. package/dist/create/board-checklist.js +1 -1
  31. package/dist/create/board-codegen.js +4 -4
  32. package/dist/create/board-spec.d.ts +74 -530
  33. package/dist/create/debug-artifacts.d.ts +20 -0
  34. package/dist/create/debug-artifacts.js +69 -0
  35. package/dist/create/editor-integration.d.ts +30 -0
  36. package/dist/create/editor-integration.js +218 -0
  37. package/dist/create/eslint-rules-template.d.ts +2 -2
  38. package/dist/create/framework-catalog.d.ts +8 -0
  39. package/dist/create/framework-catalog.js +28 -5
  40. package/dist/create/index.d.ts +9 -6
  41. package/dist/create/index.js +6 -4
  42. package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +5 -4
  43. package/dist/create/{init-scaffold.js → scaffold.js} +38 -2
  44. package/dist/create/templates.d.ts +29 -0
  45. package/dist/create/{init-templates.js → templates.js} +15 -2
  46. package/dist/create/wizard.d.ts +8 -0
  47. package/dist/create/{init-wizard.js → wizard.js} +11 -4
  48. package/dist/emit/compliance/rules.js +18 -4
  49. package/dist/emit/emitters/function-emitter-impl.js +7 -1
  50. package/dist/emit/emitters/line-appender.js +6 -0
  51. package/dist/emit/emitters/setup.js +22 -0
  52. package/dist/emit/emitters/ui-emitter.js +40 -15
  53. package/dist/emit/route-hal-op.js +55 -1
  54. package/dist/emit/statement-renderer.js +5 -2
  55. package/dist/ir/build-ir.js +46 -4
  56. package/dist/ir/expression-to-ir.js +17 -0
  57. package/dist/ir/hal/hal-emitter.js +23 -5
  58. package/dist/ir/hal/hal-plugins.js +11 -0
  59. package/dist/ir/pin-mode-validation.js +32 -9
  60. package/dist/ir/pin-state-tracking.d.ts +58 -0
  61. package/dist/ir/pin-state-tracking.js +182 -0
  62. package/dist/ir/program-analysis.d.ts +6 -0
  63. package/dist/ir/program-analysis.js +38 -0
  64. package/dist/ir/statement-to-ir.js +14 -0
  65. package/dist/ir/transformers/control-flow.js +29 -0
  66. package/dist/ir/transformers/ui-call-resolver.js +105 -1
  67. package/dist/ir/ui-element-auto-wire.js +7 -4
  68. package/dist/library/catalog.d.ts +35 -0
  69. package/dist/library/catalog.js +67 -0
  70. package/dist/library/cli.d.ts +2 -0
  71. package/dist/library/cli.js +168 -0
  72. package/dist/library/init.d.ts +25 -0
  73. package/dist/library/init.js +397 -0
  74. package/dist/library/install.d.ts +9 -0
  75. package/dist/library/install.js +80 -0
  76. package/dist/library/registry-search.d.ts +34 -0
  77. package/dist/library/registry-search.js +50 -0
  78. package/dist/library/validate.d.ts +17 -0
  79. package/dist/library/validate.js +175 -0
  80. package/dist/library-packages.d.ts +95 -0
  81. package/dist/library-packages.js +275 -0
  82. package/dist/orchestrator/graph-builder.d.ts +4 -1
  83. package/dist/orchestrator/graph-builder.js +23 -1
  84. package/dist/preview/api-shared-shim.d.ts +1 -0
  85. package/dist/preview/api-shared-shim.js +7 -0
  86. package/dist/preview/client.js +235 -2
  87. package/dist/preview/server.js +154 -62
  88. package/dist/testing.d.ts +2 -2
  89. package/dist/testing.js +1 -1
  90. package/dist/theme-tokens.d.ts +22 -0
  91. package/dist/theme-tokens.js +172 -0
  92. package/dist/transpile.js +90 -5
  93. package/dist/types.d.ts +24 -0
  94. package/dist/ui-hook.d.ts +7 -0
  95. package/dist/utils/cli.d.ts +2 -2
  96. package/dist/utils/cli.js +77 -3
  97. package/dist/utils/ui.d.ts +5 -0
  98. package/dist/utils/ui.js +7 -0
  99. package/package.json +18 -9
  100. package/dist/create/init-templates.d.ts +0 -28
  101. package/dist/create/init-wizard.d.ts +0 -8
package/dist/cli.js CHANGED
@@ -2,8 +2,10 @@
2
2
  import path from "node:path";
3
3
  import fs from "node:fs";
4
4
  import { parseCommandLine, printHelp } from "./utils/cli.js";
5
- import { scaffoldProject, printInitNextSteps, KNOWN_TARGETS, frameworksForTarget, frameworkCatalogEntry, FRAMEWORK_CATALOG, frameworkTargetProfile } from "./create/index.js";
6
- import { runInitWizard } from "./create/index.js";
5
+ import { runLibraryCommand } from "./library/cli.js";
6
+ import { scaffoldProject, printCreateNextSteps, KNOWN_TARGETS, frameworksForTarget, frameworkCatalogEntry, frameworkCompatibleWithTarget, FRAMEWORK_CATALOG, frameworkTargetProfile } from "./create/index.js";
7
+ import { generateFrameworkDebugArtifacts } from "./create/debug-artifacts.js";
8
+ import { runCreateWizard } from "./create/index.js";
7
9
  import { installProjectDependencies } from "./create/install-deps.js";
8
10
  import { generateLibraryDefinitions, transpileFile } from "./transpile.js";
9
11
  import { generateDecl, generateDeclsForDirectory, generateComponentDeclsForProject } from "./libdef/cpp-to-decl.js";
@@ -64,8 +66,9 @@ async function handleCreate(options) {
64
66
  const available = KNOWN_TARGETS.map(t => ` - ${t.id} (${t.displayName})`).join("\n");
65
67
  throw new Error(`Unknown target '${targetId}'. Available targets:\n${available}`);
66
68
  }
67
- // Resolve the framework. --framework wins; otherwise narrow via the catalog
68
- // for the chosen board and auto-pick when exactly one is compatible.
69
+ // Resolve the framework. --framework wins (validated against the board's
70
+ // compatible set); otherwise narrow via the catalog for the chosen board
71
+ // and auto-pick when exactly one is compatible.
69
72
  let frameworkId;
70
73
  let frameworkPackage;
71
74
  if (options.framework) {
@@ -74,6 +77,11 @@ async function handleCreate(options) {
74
77
  const available = FRAMEWORK_CATALOG.filter(f => f.installable).map(f => f.id).join(", ");
75
78
  throw new Error(`Unknown framework '${options.framework}'. Available: ${available}`);
76
79
  }
80
+ if (!frameworkCompatibleWithTarget(target, requested.id)) {
81
+ const list = frameworksForTarget(target).filter(f => f.installable).map(f => f.id).join(", ");
82
+ throw new Error(`Framework '${requested.id}' is not compatible with target '${target.id}' (${target.displayName}). ` +
83
+ `Compatible frameworks: ${list}`);
84
+ }
77
85
  frameworkId = requested.id;
78
86
  frameworkPackage = requested.packageName;
79
87
  }
@@ -114,7 +122,7 @@ async function handleCreate(options) {
114
122
  finalizeCreate(result, options);
115
123
  }
116
124
  else {
117
- const wizardResult = await runInitWizard({
125
+ const wizardResult = await runCreateWizard({
118
126
  projectName: options.projectName,
119
127
  board: options.board,
120
128
  framework: options.framework,
@@ -156,7 +164,20 @@ function finalizeCreate(result, options) {
156
164
  console.log(chalk.dim(` Run '${chalk.white("npm install")}' manually in ${relativeDir} when ready.`));
157
165
  }
158
166
  }
159
- printInitNextSteps(result.options, result.outDir, { installed });
167
+ // Framework starter debug profile (e.g. Zephyr esp32s3): write .vscode/
168
+ // launch.json + tasks.json so F5 in VS Code works before the first build.
169
+ // Runs after the install step so the framework package resolves from the
170
+ // new project's node_modules; best-effort — the first --debug build writes
171
+ // the artifacts anyway.
172
+ const debugArtifacts = generateFrameworkDebugArtifacts({
173
+ frameworkPackage: result.options.frameworkPackage || undefined,
174
+ workspaceRoot: result.outDir,
175
+ buildTarget: result.options.buildTarget,
176
+ });
177
+ if (debugArtifacts.length > 0) {
178
+ console.log(`\n${chalk.green("✓")} Debug profile: ${debugArtifacts.map((f) => chalk.white(f)).join(", ")}`);
179
+ }
180
+ printCreateNextSteps(result.options, result.outDir, { installed, debugProfile: debugArtifacts.length > 0 });
160
181
  }
161
182
  async function handleBoardAdd(options) {
162
183
  const { scaffoldBoardPackages, parseBoardSpec, generateFrameworkChecklist } = await import("./create/index.js");
@@ -189,6 +210,10 @@ async function main() {
189
210
  await handleBoardAdd(options);
190
211
  return;
191
212
  }
213
+ if (options.command === "library") {
214
+ await runLibraryCommand(options);
215
+ return;
216
+ }
192
217
  if (options.command === "preview") {
193
218
  await runPreviewServer({
194
219
  configPath: options.configPath,
@@ -570,7 +595,6 @@ async function main() {
570
595
  buildTarget,
571
596
  port: effectivePort,
572
597
  baud: options.baud ?? config?.console?.baudRate,
573
- optimize: config?.outputOptimize,
574
598
  extraFlags: config?.outputExtraFlags,
575
599
  defines: psramDefines,
576
600
  psram: config?.psram,
@@ -671,7 +695,6 @@ async function main() {
671
695
  buildTarget,
672
696
  port: effectivePort,
673
697
  baud: options.baud ?? config?.console?.baudRate,
674
- optimize: config?.outputOptimize,
675
698
  extraFlags: config?.outputExtraFlags,
676
699
  defines: psramDefines,
677
700
  psram: config?.psram,
@@ -779,7 +802,6 @@ async function main() {
779
802
  buildTarget,
780
803
  port: effectivePort,
781
804
  baud: options.baud ?? config?.console?.baudRate,
782
- optimize: config?.outputOptimize,
783
805
  extraFlags: config?.outputExtraFlags,
784
806
  defines: psramDefines,
785
807
  psram: config?.psram,
@@ -15,8 +15,6 @@ export interface ResolvedCuttlefishConfig {
15
15
  buildTarget?: string;
16
16
  /** Output framework (e.g. 'arduino'). */
17
17
  outputFramework?: string;
18
- /** Optimization level. */
19
- outputOptimize?: string;
20
18
  /** Output directory. */
21
19
  outputOutDir?: string;
22
20
  /**
@@ -415,9 +415,15 @@ export function parseConfigFile(configPath) {
415
415
  const outputFramework = flat.get("output.framework");
416
416
  if (typeof outputFramework === "string")
417
417
  resolved.outputFramework = outputFramework;
418
- const outputOptimize = flat.get("output.optimize");
419
- if (typeof outputOptimize === "string")
420
- resolved.outputOptimize = outputOptimize;
418
+ // `output.optimize` is removed: no framework ever consumed it (the only
419
+ // consumer, framework-esp32, is deleted). Warn-and-drop instead of failing
420
+ // strict validation, so existing configs keep building while telling the
421
+ // user to delete the key. Optimization is framework territory — e.g.
422
+ // `zephyr.kconfig` CONFIG_*_OPTIMIZATIONS symbols.
423
+ if (flat.has("output.optimize")) {
424
+ warn("'output.optimize' has no effect and is deprecated — remove it. " +
425
+ "Control optimization via the framework (e.g. zephyr.kconfig CONFIG_SIZE_OPTIMIZATIONS / CONFIG_SPEED_OPTIMIZATIONS).");
426
+ }
421
427
  const outputOutDir = flat.get("output.outDir");
422
428
  if (typeof outputOutDir === "string")
423
429
  resolved.outputOutDir = outputOutDir;
@@ -444,11 +450,13 @@ export function parseConfigFile(configPath) {
444
450
  // Parse zephyr-specific config section.
445
451
  const zephyrKconfig = extractStringRecord(configObject, ["zephyr", "kconfig"], warn);
446
452
  const zephyrCmakeArgs = extractStringArray(configObject, ["zephyr", "cmakeArgs"], warn);
453
+ const zephyrRunnerArgs = extractStringArray(configObject, ["zephyr", "runnerArgs"], warn);
447
454
  const zephyrRunner = flat.get("zephyr.runner");
448
- if (zephyrKconfig || zephyrCmakeArgs || typeof zephyrRunner === "string") {
455
+ if (zephyrKconfig || zephyrCmakeArgs || zephyrRunnerArgs || typeof zephyrRunner === "string") {
449
456
  resolved.zephyrConfig = {
450
457
  ...(zephyrKconfig ? { kconfig: zephyrKconfig } : {}),
451
458
  ...(zephyrCmakeArgs ? { cmakeArgs: zephyrCmakeArgs } : {}),
459
+ ...(zephyrRunnerArgs ? { runnerArgs: zephyrRunnerArgs } : {}),
452
460
  ...(typeof zephyrRunner === "string" ? { runner: zephyrRunner } : {}),
453
461
  };
454
462
  }
@@ -478,10 +486,9 @@ export function parseConfigFile(configPath) {
478
486
  // PsramType enum and fails validation instead of vanishing.
479
487
  if (resolved.psram !== undefined)
480
488
  structuredForValidation.psram = resolved.psram;
481
- if (resolved.outputFramework || resolved.outputOptimize || resolved.outputOutDir || resolved.outputExtraFlags || resolved.outputDefines) {
489
+ if (resolved.outputFramework || resolved.outputOutDir || resolved.outputExtraFlags || resolved.outputDefines) {
482
490
  structuredForValidation.output = {
483
491
  ...(resolved.outputFramework ? { framework: resolved.outputFramework } : {}),
484
- ...(resolved.outputOptimize ? { optimize: resolved.outputOptimize } : {}),
485
492
  ...(resolved.outputOutDir ? { outDir: resolved.outputOutDir } : {}),
486
493
  ...(resolved.outputExtraFlags ? { extraFlags: resolved.outputExtraFlags } : {}),
487
494
  ...(resolved.outputDefines ? { defines: resolved.outputDefines } : {}),
@@ -4,264 +4,51 @@ import { z } from 'zod';
4
4
  *
5
5
  * `target` and `board` are required. Everything else is optional.
6
6
  */
7
- export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
7
+ export declare const CuttlefishConfigSchema: z.ZodObject<{
8
8
  entry: z.ZodOptional<z.ZodString>;
9
9
  target: z.ZodOptional<z.ZodString>;
10
10
  mcu: z.ZodOptional<z.ZodString>;
11
11
  board: z.ZodOptional<z.ZodString>;
12
12
  contract: z.ZodOptional<z.ZodString>;
13
13
  framework: z.ZodOptional<z.ZodString>;
14
- /** ESP32 PSRAM type. When set, the framework emits the PSRAM-enabling
15
- * Kconfig/define so canvas allocations prefer external RAM (large scroll
16
- * viewports/lists stop failing on PSRAM targets). No effect on boards
17
- * without PSRAM (the runtime falls back to SRAM then the band renderer). */
18
- psram: z.ZodOptional<z.ZodEnum<["opi", "quad"]>>;
14
+ psram: z.ZodOptional<z.ZodEnum<{
15
+ opi: "opi";
16
+ quad: "quad";
17
+ }>>;
19
18
  output: z.ZodOptional<z.ZodObject<{
20
19
  framework: z.ZodOptional<z.ZodString>;
21
- optimize: z.ZodOptional<z.ZodEnum<["none", "size", "speed", "balanced"]>>;
22
20
  outDir: z.ZodOptional<z.ZodString>;
23
21
  defines: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
24
- extraFlags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
- }, "strict", z.ZodTypeAny, {
26
- framework?: string | undefined;
27
- outDir?: string | undefined;
28
- optimize?: "none" | "size" | "speed" | "balanced" | undefined;
29
- defines?: Record<string, string> | undefined;
30
- extraFlags?: string[] | undefined;
31
- }, {
32
- framework?: string | undefined;
33
- outDir?: string | undefined;
34
- optimize?: "none" | "size" | "speed" | "balanced" | undefined;
35
- defines?: Record<string, string> | undefined;
36
- extraFlags?: string[] | undefined;
37
- }>>;
22
+ extraFlags: z.ZodOptional<z.ZodArray<z.ZodString>>;
23
+ }, z.core.$strict>>;
38
24
  frameworkData: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
39
- include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
40
- exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
25
+ include: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
27
  test: z.ZodOptional<z.ZodObject<{
42
- include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
28
+ include: z.ZodOptional<z.ZodArray<z.ZodString>>;
43
29
  port: z.ZodOptional<z.ZodString>;
44
30
  baudRate: z.ZodOptional<z.ZodNumber>;
45
31
  timeout: z.ZodOptional<z.ZodNumber>;
46
32
  buildTarget: z.ZodOptional<z.ZodString>;
47
33
  board: z.ZodOptional<z.ZodString>;
48
- }, "strict", z.ZodTypeAny, {
49
- port?: string | undefined;
50
- include?: string[] | undefined;
51
- board?: string | undefined;
52
- timeout?: number | undefined;
53
- buildTarget?: string | undefined;
54
- baudRate?: number | undefined;
55
- }, {
56
- port?: string | undefined;
57
- include?: string[] | undefined;
58
- board?: string | undefined;
59
- timeout?: number | undefined;
60
- buildTarget?: string | undefined;
61
- baudRate?: number | undefined;
62
- }>>;
34
+ }, z.core.$strict>>;
63
35
  toolchain: z.ZodOptional<z.ZodObject<{
64
36
  type: z.ZodOptional<z.ZodString>;
65
37
  frameworkOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
66
- }, "strict", z.ZodTypeAny, {
67
- type?: string | undefined;
68
- frameworkOptions?: Record<string, unknown> | undefined;
69
- }, {
70
- type?: string | undefined;
71
- frameworkOptions?: Record<string, unknown> | undefined;
72
- }>>;
38
+ }, z.core.$strict>>;
73
39
  console: z.ZodOptional<z.ZodObject<{
74
40
  baudRate: z.ZodOptional<z.ZodNumber>;
75
41
  port: z.ZodOptional<z.ZodString>;
76
- }, "strict", z.ZodTypeAny, {
77
- port?: string | undefined;
78
- baudRate?: number | undefined;
79
- }, {
80
- port?: string | undefined;
81
- baudRate?: number | undefined;
82
- }>>;
42
+ }, z.core.$strict>>;
83
43
  native: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
84
- /** Display profile config (driver, wiring, touch) — loosely typed here so
85
- * the loader's presence/shape extraction round-trips through validation. */
86
44
  display: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
87
45
  zephyr: z.ZodOptional<z.ZodObject<{
88
46
  kconfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
89
- cmakeArgs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
47
+ cmakeArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
90
48
  runner: z.ZodOptional<z.ZodString>;
91
- }, "strict", z.ZodTypeAny, {
92
- kconfig?: Record<string, string> | undefined;
93
- cmakeArgs?: string[] | undefined;
94
- runner?: string | undefined;
95
- }, {
96
- kconfig?: Record<string, string> | undefined;
97
- cmakeArgs?: string[] | undefined;
98
- runner?: string | undefined;
99
- }>>;
100
- }, "strict", z.ZodTypeAny, {
101
- console?: {
102
- port?: string | undefined;
103
- baudRate?: number | undefined;
104
- } | undefined;
105
- frameworkData?: Record<string, unknown> | undefined;
106
- target?: string | undefined;
107
- output?: {
108
- framework?: string | undefined;
109
- outDir?: string | undefined;
110
- optimize?: "none" | "size" | "speed" | "balanced" | undefined;
111
- defines?: Record<string, string> | undefined;
112
- extraFlags?: string[] | undefined;
113
- } | undefined;
114
- include?: string[] | undefined;
115
- board?: string | undefined;
116
- entry?: string | undefined;
117
- display?: Record<string, unknown> | undefined;
118
- exclude?: string[] | undefined;
119
- toolchain?: {
120
- type?: string | undefined;
121
- frameworkOptions?: Record<string, unknown> | undefined;
122
- } | undefined;
123
- zephyr?: {
124
- kconfig?: Record<string, string> | undefined;
125
- cmakeArgs?: string[] | undefined;
126
- runner?: string | undefined;
127
- } | undefined;
128
- framework?: string | undefined;
129
- native?: Record<string, unknown> | undefined;
130
- mcu?: string | undefined;
131
- contract?: string | undefined;
132
- psram?: "opi" | "quad" | undefined;
133
- test?: {
134
- port?: string | undefined;
135
- include?: string[] | undefined;
136
- board?: string | undefined;
137
- timeout?: number | undefined;
138
- buildTarget?: string | undefined;
139
- baudRate?: number | undefined;
140
- } | undefined;
141
- }, {
142
- console?: {
143
- port?: string | undefined;
144
- baudRate?: number | undefined;
145
- } | undefined;
146
- frameworkData?: Record<string, unknown> | undefined;
147
- target?: string | undefined;
148
- output?: {
149
- framework?: string | undefined;
150
- outDir?: string | undefined;
151
- optimize?: "none" | "size" | "speed" | "balanced" | undefined;
152
- defines?: Record<string, string> | undefined;
153
- extraFlags?: string[] | undefined;
154
- } | undefined;
155
- include?: string[] | undefined;
156
- board?: string | undefined;
157
- entry?: string | undefined;
158
- display?: Record<string, unknown> | undefined;
159
- exclude?: string[] | undefined;
160
- toolchain?: {
161
- type?: string | undefined;
162
- frameworkOptions?: Record<string, unknown> | undefined;
163
- } | undefined;
164
- zephyr?: {
165
- kconfig?: Record<string, string> | undefined;
166
- cmakeArgs?: string[] | undefined;
167
- runner?: string | undefined;
168
- } | undefined;
169
- framework?: string | undefined;
170
- native?: Record<string, unknown> | undefined;
171
- mcu?: string | undefined;
172
- contract?: string | undefined;
173
- psram?: "opi" | "quad" | undefined;
174
- test?: {
175
- port?: string | undefined;
176
- include?: string[] | undefined;
177
- board?: string | undefined;
178
- timeout?: number | undefined;
179
- buildTarget?: string | undefined;
180
- baudRate?: number | undefined;
181
- } | undefined;
182
- }>, {
183
- console?: {
184
- port?: string | undefined;
185
- baudRate?: number | undefined;
186
- } | undefined;
187
- frameworkData?: Record<string, unknown> | undefined;
188
- target?: string | undefined;
189
- output?: {
190
- framework?: string | undefined;
191
- outDir?: string | undefined;
192
- optimize?: "none" | "size" | "speed" | "balanced" | undefined;
193
- defines?: Record<string, string> | undefined;
194
- extraFlags?: string[] | undefined;
195
- } | undefined;
196
- include?: string[] | undefined;
197
- board?: string | undefined;
198
- entry?: string | undefined;
199
- display?: Record<string, unknown> | undefined;
200
- exclude?: string[] | undefined;
201
- toolchain?: {
202
- type?: string | undefined;
203
- frameworkOptions?: Record<string, unknown> | undefined;
204
- } | undefined;
205
- zephyr?: {
206
- kconfig?: Record<string, string> | undefined;
207
- cmakeArgs?: string[] | undefined;
208
- runner?: string | undefined;
209
- } | undefined;
210
- framework?: string | undefined;
211
- native?: Record<string, unknown> | undefined;
212
- mcu?: string | undefined;
213
- contract?: string | undefined;
214
- psram?: "opi" | "quad" | undefined;
215
- test?: {
216
- port?: string | undefined;
217
- include?: string[] | undefined;
218
- board?: string | undefined;
219
- timeout?: number | undefined;
220
- buildTarget?: string | undefined;
221
- baudRate?: number | undefined;
222
- } | undefined;
223
- }, {
224
- console?: {
225
- port?: string | undefined;
226
- baudRate?: number | undefined;
227
- } | undefined;
228
- frameworkData?: Record<string, unknown> | undefined;
229
- target?: string | undefined;
230
- output?: {
231
- framework?: string | undefined;
232
- outDir?: string | undefined;
233
- optimize?: "none" | "size" | "speed" | "balanced" | undefined;
234
- defines?: Record<string, string> | undefined;
235
- extraFlags?: string[] | undefined;
236
- } | undefined;
237
- include?: string[] | undefined;
238
- board?: string | undefined;
239
- entry?: string | undefined;
240
- display?: Record<string, unknown> | undefined;
241
- exclude?: string[] | undefined;
242
- toolchain?: {
243
- type?: string | undefined;
244
- frameworkOptions?: Record<string, unknown> | undefined;
245
- } | undefined;
246
- zephyr?: {
247
- kconfig?: Record<string, string> | undefined;
248
- cmakeArgs?: string[] | undefined;
249
- runner?: string | undefined;
250
- } | undefined;
251
- framework?: string | undefined;
252
- native?: Record<string, unknown> | undefined;
253
- mcu?: string | undefined;
254
- contract?: string | undefined;
255
- psram?: "opi" | "quad" | undefined;
256
- test?: {
257
- port?: string | undefined;
258
- include?: string[] | undefined;
259
- board?: string | undefined;
260
- timeout?: number | undefined;
261
- buildTarget?: string | undefined;
262
- baudRate?: number | undefined;
263
- } | undefined;
264
- }>;
49
+ runnerArgs: z.ZodOptional<z.ZodArray<z.ZodString>>;
50
+ }, z.core.$strict>>;
51
+ }, z.core.$strict>;
265
52
  /** Inferred TypeScript type from the Zod schema. */
266
53
  export type ValidatedCuttlefishConfig = z.infer<typeof CuttlefishConfigSchema>;
267
54
  /**
@@ -6,14 +6,11 @@
6
6
  // enum constraints before the config is used by the transpiler.
7
7
  // ---------------------------------------------------------------------------
8
8
  import { z } from 'zod';
9
- /** Optimization levels accepted by the output.optimize field. */
10
- const OptimizationLevel = z.enum(['none', 'size', 'speed', 'balanced']);
11
9
  /** PSRAM types accepted by the top-level `psram` field (ESP32 PSRAM variants). */
12
10
  const PsramType = z.enum(['opi', 'quad']);
13
11
  /** Schema for the `output` section. */
14
12
  const OutputConfig = z.object({
15
13
  framework: z.string().min(1).optional(),
16
- optimize: OptimizationLevel.optional(),
17
14
  outDir: z.string().optional(),
18
15
  defines: z.record(z.string(), z.string()).optional(),
19
16
  extraFlags: z.array(z.string()).optional(),
@@ -42,6 +39,7 @@ const ZephyrConfig = z.object({
42
39
  kconfig: z.record(z.string(), z.string()).optional(),
43
40
  cmakeArgs: z.array(z.string()).optional(),
44
41
  runner: z.string().optional(),
42
+ runnerArgs: z.array(z.string()).optional(),
45
43
  }).strict();
46
44
  /**
47
45
  * Schema for the full CuttlefishConfig shape.
@@ -11,13 +11,7 @@ export declare const CONTRACT_VERSION: 1;
11
11
  declare const ContractComponentSchema: z.ZodObject<{
12
12
  reference: z.ZodString;
13
13
  dnp: z.ZodBoolean;
14
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
15
- reference: z.ZodString;
16
- dnp: z.ZodBoolean;
17
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
18
- reference: z.ZodString;
19
- dnp: z.ZodBoolean;
20
- }, z.ZodTypeAny, "passthrough">>;
14
+ }, z.core.$loose>;
21
15
  /**
22
16
  * Info about a single connected MCU pin. The fields cuttlefish consumes
23
17
  * (pinName, pinType, net) are required; boardName is optional (present only
@@ -31,46 +25,14 @@ declare const ContractPinSchema: z.ZodObject<{
31
25
  externalComponents: z.ZodDefault<z.ZodArray<z.ZodObject<{
32
26
  reference: z.ZodString;
33
27
  dnp: z.ZodBoolean;
34
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
35
- reference: z.ZodString;
36
- dnp: z.ZodBoolean;
37
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
38
- reference: z.ZodString;
39
- dnp: z.ZodBoolean;
40
- }, z.ZodTypeAny, "passthrough">>, "many">>;
41
- }, "strict", z.ZodTypeAny, {
42
- pinName: string;
43
- pinType: string;
44
- net: string;
45
- externalComponents: z.objectOutputType<{
46
- reference: z.ZodString;
47
- dnp: z.ZodBoolean;
48
- }, z.ZodTypeAny, "passthrough">[];
49
- boardName?: string | undefined;
50
- }, {
51
- pinName: string;
52
- pinType: string;
53
- net: string;
54
- boardName?: string | undefined;
55
- externalComponents?: z.objectInputType<{
56
- reference: z.ZodString;
57
- dnp: z.ZodBoolean;
58
- }, z.ZodTypeAny, "passthrough">[] | undefined;
59
- }>;
28
+ }, z.core.$loose>>>;
29
+ }, z.core.$strict>;
60
30
  /** Which peripheral buses have all their required pins wired. */
61
31
  declare const AvailablePeripheralsSchema: z.ZodObject<{
62
32
  i2c: z.ZodBoolean;
63
33
  spi: z.ZodBoolean;
64
34
  uart: z.ZodBoolean;
65
- }, "strict", z.ZodTypeAny, {
66
- i2c: boolean;
67
- spi: boolean;
68
- uart: boolean;
69
- }, {
70
- i2c: boolean;
71
- spi: boolean;
72
- uart: boolean;
73
- }>;
35
+ }, z.core.$strict>;
74
36
  /**
75
37
  * The top-level contract object. `.strict()` so a future v2 contract with new
76
38
  * top-level keys is rejected clearly (complementing the version check) rather
@@ -80,11 +42,7 @@ export declare const HwContractSchema: z.ZodObject<{
80
42
  version: z.ZodLiteral<1>;
81
43
  mcu: z.ZodObject<{
82
44
  symbol: z.ZodString;
83
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
84
- symbol: z.ZodString;
85
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
86
- symbol: z.ZodString;
87
- }, z.ZodTypeAny, "passthrough">>;
45
+ }, z.core.$loose>;
88
46
  connectedPins: z.ZodRecord<z.ZodString, z.ZodObject<{
89
47
  pinName: z.ZodString;
90
48
  pinType: z.ZodString;
@@ -93,90 +51,14 @@ export declare const HwContractSchema: z.ZodObject<{
93
51
  externalComponents: z.ZodDefault<z.ZodArray<z.ZodObject<{
94
52
  reference: z.ZodString;
95
53
  dnp: z.ZodBoolean;
96
- }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
97
- reference: z.ZodString;
98
- dnp: z.ZodBoolean;
99
- }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
100
- reference: z.ZodString;
101
- dnp: z.ZodBoolean;
102
- }, z.ZodTypeAny, "passthrough">>, "many">>;
103
- }, "strict", z.ZodTypeAny, {
104
- pinName: string;
105
- pinType: string;
106
- net: string;
107
- externalComponents: z.objectOutputType<{
108
- reference: z.ZodString;
109
- dnp: z.ZodBoolean;
110
- }, z.ZodTypeAny, "passthrough">[];
111
- boardName?: string | undefined;
112
- }, {
113
- pinName: string;
114
- pinType: string;
115
- net: string;
116
- boardName?: string | undefined;
117
- externalComponents?: z.objectInputType<{
118
- reference: z.ZodString;
119
- dnp: z.ZodBoolean;
120
- }, z.ZodTypeAny, "passthrough">[] | undefined;
121
- }>>;
54
+ }, z.core.$loose>>>;
55
+ }, z.core.$strict>>;
122
56
  availablePeripherals: z.ZodObject<{
123
57
  i2c: z.ZodBoolean;
124
58
  spi: z.ZodBoolean;
125
59
  uart: z.ZodBoolean;
126
- }, "strict", z.ZodTypeAny, {
127
- i2c: boolean;
128
- spi: boolean;
129
- uart: boolean;
130
- }, {
131
- i2c: boolean;
132
- spi: boolean;
133
- uart: boolean;
134
- }>;
135
- }, "strict", z.ZodTypeAny, {
136
- mcu: {
137
- symbol: string;
138
- } & {
139
- [k: string]: unknown;
140
- };
141
- version: 1;
142
- connectedPins: Record<string, {
143
- pinName: string;
144
- pinType: string;
145
- net: string;
146
- externalComponents: z.objectOutputType<{
147
- reference: z.ZodString;
148
- dnp: z.ZodBoolean;
149
- }, z.ZodTypeAny, "passthrough">[];
150
- boardName?: string | undefined;
151
- }>;
152
- availablePeripherals: {
153
- i2c: boolean;
154
- spi: boolean;
155
- uart: boolean;
156
- };
157
- }, {
158
- mcu: {
159
- symbol: string;
160
- } & {
161
- [k: string]: unknown;
162
- };
163
- version: 1;
164
- connectedPins: Record<string, {
165
- pinName: string;
166
- pinType: string;
167
- net: string;
168
- boardName?: string | undefined;
169
- externalComponents?: z.objectInputType<{
170
- reference: z.ZodString;
171
- dnp: z.ZodBoolean;
172
- }, z.ZodTypeAny, "passthrough">[] | undefined;
173
- }>;
174
- availablePeripherals: {
175
- i2c: boolean;
176
- spi: boolean;
177
- uart: boolean;
178
- };
179
- }>;
60
+ }, z.core.$strict>;
61
+ }, z.core.$strict>;
180
62
  export type ContractComponent = z.infer<typeof ContractComponentSchema>;
181
63
  export type ContractPin = z.infer<typeof ContractPinSchema>;
182
64
  export type AvailablePeripherals = z.infer<typeof AvailablePeripheralsSchema>;
@@ -37,7 +37,7 @@ export function generateFrameworkChecklist(spec) {
37
37
  '',
38
38
  'Then rebuild and test:',
39
39
  ' npm run build --workspaces',
40
- ' npx vitest run tests/packages/transpiler/init-scaffold.test.ts',
40
+ ' npx vitest run tests/packages/transpiler/scaffold.test.ts',
41
41
  ' npx vitest run tests/packages/framework-arduino/',
42
42
  '',
43
43
  ];
@@ -4,7 +4,7 @@
4
4
  // registry/tests/README (idempotently), and returns the file list + the
5
5
  // framework-anticipation checklist.
6
6
  //
7
- // Pattern: mirrors init-scaffold.ts's scaffoldProject — a writeFile closure
7
+ // Pattern: mirrors scaffold.ts's scaffoldProject — a writeFile closure
8
8
  // + fs.writeFileSync + tracks createdFiles.
9
9
  // ---------------------------------------------------------------------------
10
10
  import path from 'node:path';
@@ -100,12 +100,12 @@ export function scaffoldBoardPackages(spec, opts = {}) {
100
100
  }
101
101
  catch { /* best-effort: skip if package.json isn't valid */ }
102
102
  }
103
- // 2. init-scaffold.ts registry entry
104
- const scaffoldPath = path.join(rootDir, 'packages', 'cuttlefish', 'src', 'create', 'init-scaffold.ts');
103
+ // 2. scaffold.ts registry entry
104
+ const scaffoldPath = path.join(rootDir, 'packages', 'cuttlefish', 'src', 'create', 'scaffold.ts');
105
105
  const registryEntry = ` {\n id: '${spec.boardId}',\n displayName: '${spec.boardName}',\n isNative: false,\n architecture: '${arch}',\n boardPackage: '@typecad/board-${arch}',\n frameworkPackage: '@typecad/framework-arduino',\n framework: 'arduino',\n buildTarget: '${spec.fqbn}',\n mcu: '${arch}',\n },\n`;
106
106
  insertAfter(scaffoldPath, " _knownTargets: KnownTarget[] = [", registryEntry, `'${spec.boardId}'`);
107
107
  // 3. KNOWN_BOARDS test
108
- const testPath = path.join(rootDir, 'tests', 'packages', 'transpiler', 'init-scaffold.test.ts');
108
+ const testPath = path.join(rootDir, 'tests', 'packages', 'transpiler', 'scaffold.test.ts');
109
109
  const testEntry = `
110
110
  it("contains ${spec.boardId}", () => {
111
111
  const b = KNOWN_BOARDS.find(b => b.id === '${spec.boardId}');