@typecad/cuttlefish 1.0.0-alpha.3 → 1.0.0-alpha.7
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.
- package/README.md +4 -4
- package/dist/api/shared/display-adapter.d.ts +2 -1
- package/dist/api/shared/display-adapter.js +8 -1
- package/dist/api/shared/display-adapters/sdl.js +9 -2
- package/dist/api/shared/display-profile.d.ts +20 -3
- package/dist/api/shared/display-profile.js +21 -6
- package/dist/api/shared/framework-manifest-registry.d.ts +9 -0
- package/dist/api/shared/framework-manifest-registry.js +25 -0
- package/dist/api/shared/framework-manifest.d.ts +462 -0
- package/dist/api/shared/framework-manifest.js +149 -0
- package/dist/api/shared/glcdfont.d.ts +12 -0
- package/dist/api/shared/glcdfont.js +124 -0
- package/dist/api/shared/graphics-strategy.d.ts +28 -0
- package/dist/api/shared/hal-op-ir.d.ts +427 -1
- package/dist/api/shared/hal-op-ir.js +95 -1
- package/dist/api/shared/index.d.ts +11 -1
- package/dist/api/shared/index.js +14 -0
- package/dist/api/shared/native-display-op-resolver.d.ts +10 -0
- package/dist/api/shared/native-display-op-resolver.js +64 -0
- package/dist/api/shared/platform-strategy.d.ts +9 -0
- package/dist/api/shared/promise-runtime.js +78 -0
- package/dist/api/shared/types.d.ts +8 -0
- package/dist/api/shared/validate-framework-manifest.d.ts +28 -0
- package/dist/api/shared/validate-framework-manifest.js +417 -0
- package/dist/cli-utils.d.ts +1 -0
- package/dist/cli-utils.js +3 -1
- package/dist/cli.js +175 -4
- package/dist/config-loader.js +20 -1
- package/dist/config-schema.d.ts +36 -36
- package/dist/create/board-spec.d.ts +4 -4
- package/dist/create/index.d.ts +1 -1
- package/dist/create/index.js +1 -1
- package/dist/create/init-scaffold.d.ts +3 -0
- package/dist/create/init-scaffold.js +74 -2
- package/dist/create/init-templates.d.ts +4 -0
- package/dist/create/init-templates.js +217 -17
- package/dist/create/init-wizard.js +20 -1
- package/dist/emit/cpp-emitter.js +4 -3
- package/dist/emit/emitters/emitter-context.d.ts +5 -0
- package/dist/emit/emitters/function-emitter-impl.js +69 -59
- package/dist/emit/emitters/output-finalizer.d.ts +6 -0
- package/dist/emit/emitters/output-finalizer.js +21 -11
- package/dist/emit/emitters/setup.js +155 -0
- package/dist/emit/emitters/top-level-prep.js +2 -0
- package/dist/emit/emitters/ui-emitter.js +23 -8
- package/dist/emit/expression-renderer.js +10 -1
- package/dist/emit/snprintf-helpers.js +8 -0
- package/dist/emit/statement-renderer.js +13 -0
- package/dist/emit/utils/async-state-machine.js +185 -116
- package/dist/emit/utils/hal-op-cpp-type.d.ts +6 -0
- package/dist/emit/utils/hal-op-cpp-type.js +40 -0
- package/dist/ir/adc-range-validation.js +26 -25
- package/dist/ir/build-ir.js +5 -1
- package/dist/ir/expression-to-ir.js +57 -6
- package/dist/ir/feature-registry.js +7 -25
- package/dist/ir/hal/hal-emitter.d.ts +5 -2
- package/dist/ir/hal/hal-emitter.js +40 -12
- package/dist/ir/hal/hal-parser.d.ts +6 -0
- package/dist/ir/hal/hal-parser.js +74 -0
- package/dist/ir/hal/hal-plugins.js +571 -0
- package/dist/ir/identifier-collector.js +18 -0
- package/dist/ir/interrupt-analysis.js +8 -3
- package/dist/ir/memory-budget-validation.js +1 -0
- package/dist/ir/network-validation.d.ts +4 -0
- package/dist/ir/network-validation.js +184 -0
- package/dist/ir/ownership-analysis.js +33 -1
- package/dist/ir/peripheral-ownership.js +5 -0
- package/dist/ir/peripheral-validation.d.ts +1 -1
- package/dist/ir/peripheral-validation.js +6 -3
- package/dist/ir/pin-alias-conflict.d.ts +1 -1
- package/dist/ir/pin-alias-conflict.js +2 -1
- package/dist/ir/pin-capability-validation.js +34 -32
- package/dist/ir/pin-mode-validation.js +5 -0
- package/dist/ir/pin-safety.d.ts +1 -1
- package/dist/ir/pin-safety.js +2 -1
- package/dist/ir/program-analysis.d.ts +39 -0
- package/dist/ir/program-analysis.js +192 -0
- package/dist/ir/pulldown-validation.d.ts +1 -1
- package/dist/ir/pulldown-validation.js +2 -1
- package/dist/ir/pwm-timer-sharing.d.ts +1 -1
- package/dist/ir/pwm-timer-sharing.js +2 -1
- package/dist/ir/resource-analysis.js +2 -0
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +1 -1
- package/dist/ir/timer0-pwm-timing-conflict.js +2 -1
- package/dist/ir/timing-validation.d.ts +6 -1
- package/dist/ir/timing-validation.js +51 -12
- package/dist/ir/transformers/expressions.js +58 -0
- package/dist/ir/transformers/hal-emit-helpers.js +1 -1
- package/dist/ir/transformers/variables.js +86 -19
- package/dist/ir/try-catch-validation.js +2 -0
- package/dist/ir/type-resolution.js +2 -2
- package/dist/ir/unit-suspicion-validation.js +9 -7
- package/dist/ir/validation-orchestrator.js +9 -7
- package/dist/libdef/c-to-decl.d.ts +27 -0
- package/dist/libdef/c-to-decl.js +397 -0
- package/dist/libdef/component-decls.d.ts +2 -0
- package/dist/libdef/component-decls.js +6 -0
- package/dist/libdef/component-discovery.d.ts +43 -0
- package/dist/libdef/component-discovery.js +83 -0
- package/dist/libdef/cpp-to-decl.d.ts +9 -0
- package/dist/libdef/cpp-to-decl.js +72 -0
- package/dist/libdef/idf-discovery.d.ts +7 -0
- package/dist/libdef/idf-discovery.js +59 -0
- package/dist/libdef/registry.js +5 -2
- package/dist/licenses.d.ts +185 -0
- package/dist/licenses.js +963 -0
- package/dist/lint-cache.d.ts +59 -0
- package/dist/lint-cache.js +257 -0
- package/dist/orchestrator/graph-builder.js +6 -2
- package/dist/stores/display-profile-store.d.ts +1 -0
- package/dist/stores/display-profile-store.js +1 -0
- package/dist/testing.d.ts +4 -2
- package/dist/testing.js +4 -2
- package/dist/transpile.d.ts +3 -0
- package/dist/transpile.js +78 -32
- package/dist/types.d.ts +5 -1
- package/dist/ui-hook.d.ts +17 -1
- package/dist/utils/cli.js +71 -1
- package/dist/utils/fs.d.ts +13 -0
- package/dist/utils/fs.js +50 -0
- package/package.json +9 -4
- package/dist/ir/heap-array-validation.d.ts +0 -24
- package/dist/ir/heap-array-validation.js +0 -29
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,8 @@ import { parseCommandLine, printHelp } from "./utils/cli.js";
|
|
|
5
5
|
import { scaffoldProject, printInitNextSteps, KNOWN_TARGETS } from "./create/index.js";
|
|
6
6
|
import { runInitWizard } from "./create/index.js";
|
|
7
7
|
import { generateLibraryDefinitions, transpileFile } from "./transpile.js";
|
|
8
|
-
import { generateDecl, generateDeclsForDirectory } from "./libdef/cpp-to-decl.js";
|
|
8
|
+
import { generateDecl, generateDeclsForDirectory, generateComponentDeclsForProject } from "./libdef/cpp-to-decl.js";
|
|
9
|
+
import { discoverIdfRootForGenDecls } from "./libdef/idf-discovery.js";
|
|
9
10
|
import { mapCppLocationToTs, readSourceMap, resolveMapPath } from "./mapping/source-map.js";
|
|
10
11
|
import { compileSource, uploadFirmware, monitorDevice } from "./platform/toolchain.js";
|
|
11
12
|
import { resolveStrategy } from "./platform/registry.js";
|
|
@@ -19,6 +20,8 @@ import { runExpectTests, assertTypeScriptInput, printDiagnostics, printMappedCom
|
|
|
19
20
|
import { runPreviewServer } from "./preview/server.js";
|
|
20
21
|
import * as ui from "./utils/ui.js";
|
|
21
22
|
import chalk from "chalk";
|
|
23
|
+
import { checkArduinoEnv } from "@typecad/arduino-cli";
|
|
24
|
+
import { runLicensesPresenter } from "./licenses.js";
|
|
22
25
|
function hasFatalDiagnostics(result) {
|
|
23
26
|
return result.diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
24
27
|
}
|
|
@@ -47,8 +50,14 @@ async function handleCreate(options) {
|
|
|
47
50
|
? '@typecad/framework-avr'
|
|
48
51
|
: framework === 'arduino'
|
|
49
52
|
? '@typecad/framework-arduino'
|
|
50
|
-
:
|
|
53
|
+
: framework === 'esp32'
|
|
54
|
+
? '@typecad/framework-esp32'
|
|
55
|
+
: `@typecad/framework-${framework}`;
|
|
51
56
|
const projectName = options.projectName || 'my-project';
|
|
57
|
+
const isEspIdf = frameworkPackage === '@typecad/framework-esp32' || framework === 'esp32';
|
|
58
|
+
const idfTarget = target.frameworkData?.target
|
|
59
|
+
?? target.architecture
|
|
60
|
+
?? 'esp32';
|
|
52
61
|
const result = scaffoldProject({
|
|
53
62
|
projectName,
|
|
54
63
|
targetId: target.id,
|
|
@@ -58,10 +67,18 @@ async function handleCreate(options) {
|
|
|
58
67
|
boardPackage: target.boardPackage,
|
|
59
68
|
frameworkPackage,
|
|
60
69
|
framework,
|
|
61
|
-
buildTarget: target.buildTarget,
|
|
70
|
+
buildTarget: isEspIdf ? idfTarget : target.buildTarget,
|
|
62
71
|
mcu: target.mcu,
|
|
63
72
|
baudRate: target.isNative ? undefined : (options.baud ?? 9600),
|
|
64
73
|
includeSketch: !options.noSketch,
|
|
74
|
+
...(isEspIdf
|
|
75
|
+
? {
|
|
76
|
+
toolchainType: 'idf',
|
|
77
|
+
frameworkData: target.frameworkData ?? { target: idfTarget, buildTarget: idfTarget },
|
|
78
|
+
}
|
|
79
|
+
: target.frameworkData
|
|
80
|
+
? { frameworkData: target.frameworkData }
|
|
81
|
+
: {}),
|
|
65
82
|
}, options.outDir);
|
|
66
83
|
console.log(`\n${chalk.green("✓")} Created project files:`);
|
|
67
84
|
for (const file of result.createdFiles) {
|
|
@@ -107,6 +124,62 @@ async function handleBoardAdd(options) {
|
|
|
107
124
|
}
|
|
108
125
|
console.log(generateFrameworkChecklist(spec));
|
|
109
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* `cuttlefish doctor` — verify arduino-cli is installed and the board's core
|
|
129
|
+
* (derived from the FQBN in cuttlefish.config.ts) is present. Exits 0 if the
|
|
130
|
+
* environment is OK, non-zero otherwise. Reuses checkArduinoEnv so the
|
|
131
|
+
* detection logic is shared with the build/test gates.
|
|
132
|
+
*/
|
|
133
|
+
function runDoctor() {
|
|
134
|
+
ui.printHeader();
|
|
135
|
+
ui.printStep("Checking arduino-cli environment...");
|
|
136
|
+
const config = loadCuttlefishConfig(process.cwd());
|
|
137
|
+
const fqbn = config?.buildTarget;
|
|
138
|
+
const result = checkArduinoEnv(fqbn);
|
|
139
|
+
const check = result.check;
|
|
140
|
+
// arduino-cli presence line
|
|
141
|
+
if (check.arduinoCliInstalled) {
|
|
142
|
+
ui.printInfo(`arduino-cli .... ${check.arduinoCliVersion ?? "unknown"} ✓`);
|
|
143
|
+
}
|
|
144
|
+
else if (!result.ok && result.reason === "arduino-cli-not-found") {
|
|
145
|
+
ui.printError(`arduino-cli .... NOT FOUND on PATH`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
ui.printError(`arduino-cli .... found but unresponsive`);
|
|
149
|
+
}
|
|
150
|
+
// core presence line (only meaningful if we have an FQBN)
|
|
151
|
+
if (fqbn) {
|
|
152
|
+
if (check.requiredCore) {
|
|
153
|
+
const status = check.requiredCoreInstalled ? "installed ✓" : "NOT installed ✗";
|
|
154
|
+
const line = `${check.requiredCore} ....... ${status}`;
|
|
155
|
+
if (check.requiredCoreInstalled) {
|
|
156
|
+
ui.printInfo(line);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
ui.printError(line);
|
|
160
|
+
ui.printInfo(` → run: arduino-cli core install ${check.requiredCore}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
ui.printInfo("(no buildTarget in cuttlefish.config.ts — skipping core check)");
|
|
166
|
+
}
|
|
167
|
+
// Exit code
|
|
168
|
+
if (result.ok) {
|
|
169
|
+
ui.printSuccess("Environment OK");
|
|
170
|
+
return; // exitCode stays unset => 0
|
|
171
|
+
}
|
|
172
|
+
if (!result.ok) {
|
|
173
|
+
for (const line of result.messages)
|
|
174
|
+
ui.printInfo(line);
|
|
175
|
+
process.exitCode = 1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* `cuttlefish licenses` dispatch — the presenter lives in licenses.ts so it is
|
|
180
|
+
* unit-testable without importing this binary entry module (cli.ts has a
|
|
181
|
+
* shebang and runs main() at import time). See runLicensesPresenter.
|
|
182
|
+
*/
|
|
110
183
|
async function main() {
|
|
111
184
|
try {
|
|
112
185
|
const options = parseCommandLine(process.argv);
|
|
@@ -154,6 +227,14 @@ async function main() {
|
|
|
154
227
|
}
|
|
155
228
|
return;
|
|
156
229
|
}
|
|
230
|
+
if (options.command === "doctor") {
|
|
231
|
+
runDoctor();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (options.command === "licenses") {
|
|
235
|
+
runLicensesPresenter(options.strict ?? false, options.all ?? false);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
157
238
|
// ── Handle build command — entry point comes from config ──────────
|
|
158
239
|
if (options.command === "build") {
|
|
159
240
|
const buildConfig = loadCuttlefishConfig(process.cwd());
|
|
@@ -184,6 +265,47 @@ async function main() {
|
|
|
184
265
|
// it intentionally has no inputFile (it scans scanDir instead), so the
|
|
185
266
|
// generic "Missing input file path" check would otherwise block it.
|
|
186
267
|
if (options.command === "gen-decls") {
|
|
268
|
+
// Check for --components flag (ESP-IDF components: managed + local).
|
|
269
|
+
// Runs before scanDir/single-file branches; components mode has no
|
|
270
|
+
// inputFile by design (it scans managed_components/ + components/).
|
|
271
|
+
const componentsDir = options.componentsDir;
|
|
272
|
+
if (componentsDir) {
|
|
273
|
+
ui.printHeader();
|
|
274
|
+
ui.printStep(`Generating component declarations for ${componentsDir}...`);
|
|
275
|
+
const config = loadCuttlefishConfig(componentsDir);
|
|
276
|
+
const frameworkConfig = (config?.frameworkConfig ?? {});
|
|
277
|
+
const componentsNode = frameworkConfig?.components ?? {};
|
|
278
|
+
const managedSpecs = Object.keys(componentsNode.managed ?? {});
|
|
279
|
+
// idf.py stores managed deps as <namespace>__<name> (slashes → __).
|
|
280
|
+
const managedNames = managedSpecs.map((spec) => spec.replace("/", "__"));
|
|
281
|
+
const localPaths = (componentsNode.local ?? []).map((p) => path.isAbsolute(p) ? p : path.resolve(componentsDir, p));
|
|
282
|
+
const builtinNames = componentsNode.builtin ?? [];
|
|
283
|
+
// Built-in components resolve against an ESP-IDF install. The CLI
|
|
284
|
+
// uses minimal discovery (env var + well-known paths). If no install
|
|
285
|
+
// is found, builtins are skipped with a notice — the framework-esp32
|
|
286
|
+
// compile path performs richer discovery and is the primary entry
|
|
287
|
+
// point for builtin gen-decls.
|
|
288
|
+
const idfRoot = discoverIdfRootForGenDecls();
|
|
289
|
+
if (builtinNames.length > 0 && !idfRoot) {
|
|
290
|
+
ui.printInfo('components.builtin declared but no ESP-IDF install was found; skipping builtin headers. ' +
|
|
291
|
+
'Run via `cuttlefish build --compile` (which performs full IDF discovery) or set $IDF_PATH.');
|
|
292
|
+
}
|
|
293
|
+
const created = generateComponentDeclsForProject(componentsDir, {
|
|
294
|
+
managed: managedNames,
|
|
295
|
+
local: localPaths,
|
|
296
|
+
builtin: idfRoot ? builtinNames : [],
|
|
297
|
+
idfRoot,
|
|
298
|
+
});
|
|
299
|
+
if (created.length === 0) {
|
|
300
|
+
ui.printInfo("No component declaration files created.");
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
ui.printSuccess(`Created ${created.length} declaration file(s):`);
|
|
304
|
+
for (const f of created)
|
|
305
|
+
ui.printFileCreated(f);
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
187
309
|
// Check for --all flag (scan directory)
|
|
188
310
|
const scanDir = options.scanDir;
|
|
189
311
|
if (scanDir) {
|
|
@@ -255,6 +377,47 @@ async function main() {
|
|
|
255
377
|
// ── Load cuttlefish.config.ts (config wins over CLI flags) ──────────
|
|
256
378
|
const inputDir = path.dirname(path.resolve(options.inputFile));
|
|
257
379
|
const config = loadCuttlefishConfig(inputDir);
|
|
380
|
+
// ── Pre-transpile: generate component .d.ts stubs ───────────────────
|
|
381
|
+
// The transpile type-check needs the .d.ts imports in main.ts to resolve.
|
|
382
|
+
// For ESP-IDF builtin/managed/local components, those .d.ts files are
|
|
383
|
+
// generated by gen-decls — so we must run it BEFORE type-checking, not
|
|
384
|
+
// only as part of --compile. The cache is written under the transpile
|
|
385
|
+
// output dir (the same path --compile uses), so user imports resolve
|
|
386
|
+
// identically in both flows.
|
|
387
|
+
if (config?.frameworkConfig) {
|
|
388
|
+
const fc = config.frameworkConfig;
|
|
389
|
+
const componentsNode = fc?.components ?? {};
|
|
390
|
+
const managedSpecs = Object.keys(componentsNode.managed ?? {});
|
|
391
|
+
const localPaths = (componentsNode.local ?? []).map((p) => path.isAbsolute(p) ? p : path.resolve(inputDir, p));
|
|
392
|
+
const builtinNames = componentsNode.builtin ?? [];
|
|
393
|
+
if (managedSpecs.length > 0 || localPaths.length > 0 || builtinNames.length > 0) {
|
|
394
|
+
// Resolve the transpile output dir — the cache lives under it so the
|
|
395
|
+
// framework's compile path and this pre-transpile pass agree on location.
|
|
396
|
+
// output.outDir in config is relative to the project root (inputDir);
|
|
397
|
+
// if absent, the transpile output goes alongside the entry file.
|
|
398
|
+
const outBase = config.outputOutDir
|
|
399
|
+
? path.resolve(inputDir, config.outputOutDir)
|
|
400
|
+
: inputDir;
|
|
401
|
+
// For builtins we need IDF_PATH. Use cuttlefish's minimal discovery
|
|
402
|
+
// (env var + well-known paths) — full discovery is done by
|
|
403
|
+
// framework-esp32 at --compile time. If no install is found,
|
|
404
|
+
// builtins are skipped; --compile will regenerate them.
|
|
405
|
+
const idfRoot = discoverIdfRootForGenDecls();
|
|
406
|
+
try {
|
|
407
|
+
generateComponentDeclsForProject(outBase, {
|
|
408
|
+
managed: managedSpecs.map((s) => s.replace('/', '__')),
|
|
409
|
+
local: localPaths,
|
|
410
|
+
builtin: idfRoot ? builtinNames : [],
|
|
411
|
+
idfRoot,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
// Non-fatal: if gen-decls fails (e.g. component not yet fetched),
|
|
416
|
+
// the type-checker will surface the missing-import errors with
|
|
417
|
+
// clearer context than crashing here.
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
258
421
|
// Load the UI engine (if @typecad/ui is installed) before any UI work.
|
|
259
422
|
await loadUIEngine();
|
|
260
423
|
let effectivePlatformContext = options.platformContext;
|
|
@@ -277,9 +440,17 @@ async function main() {
|
|
|
277
440
|
}
|
|
278
441
|
let configBuildTarget = config.buildTarget;
|
|
279
442
|
if (configBuildTarget) {
|
|
443
|
+
// Reconstruct frameworkData from buildTarget, preserving other fields
|
|
444
|
+
// (psram, components, etc.) from the resolved frameworkConfig so the
|
|
445
|
+
// transpile-time diagnostics (e.g. scroll-canvas-memory PSRAM budget)
|
|
446
|
+
// and the toolchain both see the full frameworkData, not just buildTarget.
|
|
447
|
+
const fcPsram = config.frameworkConfig?.psram;
|
|
280
448
|
effectivePlatformContext = {
|
|
281
449
|
architecture: configBuildTarget.split(":")?.[1]?.toLowerCase(),
|
|
282
|
-
frameworkData: {
|
|
450
|
+
frameworkData: {
|
|
451
|
+
buildTarget: configBuildTarget,
|
|
452
|
+
...(fcPsram ? { psram: fcPsram } : {}),
|
|
453
|
+
},
|
|
283
454
|
};
|
|
284
455
|
}
|
|
285
456
|
if (config.outputOutDir && !options.outDir) {
|
package/dist/config-loader.js
CHANGED
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import fs from "node:fs";
|
|
11
11
|
import ts from "typescript";
|
|
12
|
+
/** True for the framework-esp32 package or any path that resolves to it.
|
|
13
|
+
* Used to decide whether to route frameworkData → frameworkConfig so the
|
|
14
|
+
* ESP-IDF toolchain can read components, target, etc. */
|
|
15
|
+
function isEspIdfFramework(framework) {
|
|
16
|
+
return framework === "@typecad/framework-esp32" || framework.endsWith("framework-esp32");
|
|
17
|
+
}
|
|
12
18
|
import { safeValidateConfig } from "./config-schema.js";
|
|
13
19
|
/** The filename we search for when walking up directories. */
|
|
14
20
|
const CONFIG_FILENAME = "cuttlefish.config.ts";
|
|
@@ -323,8 +329,21 @@ export function parseConfigFile(configPath) {
|
|
|
323
329
|
if (outputDefines)
|
|
324
330
|
resolved.outputDefines = outputDefines;
|
|
325
331
|
const nativeSection = extractFrameworkSection(configObject, "native");
|
|
326
|
-
if (nativeSection)
|
|
332
|
+
if (nativeSection) {
|
|
327
333
|
resolved.frameworkConfig = nativeSection;
|
|
334
|
+
}
|
|
335
|
+
else if (resolved.framework && isEspIdfFramework(resolved.framework)) {
|
|
336
|
+
// ESP-IDF: route frameworkData through frameworkConfig so the toolchain
|
|
337
|
+
// can read components, target, and other framework-specific fields.
|
|
338
|
+
// extractFrameworkSection walks the AST and preserves nested shapes
|
|
339
|
+
// (components.managed, components.local, etc.).
|
|
340
|
+
const frameworkData = configObject
|
|
341
|
+
? extractFrameworkSection(configObject, "frameworkData")
|
|
342
|
+
: undefined;
|
|
343
|
+
if (frameworkData) {
|
|
344
|
+
resolved.frameworkConfig = frameworkData;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
328
347
|
// Parse display profile config (nested object with profile name, wiring, touch)
|
|
329
348
|
const displaySection = extractFrameworkSection(configObject, "display");
|
|
330
349
|
if (displaySection)
|
package/dist/config-schema.d.ts
CHANGED
|
@@ -41,16 +41,16 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
41
41
|
buildTarget: z.ZodOptional<z.ZodString>;
|
|
42
42
|
board: z.ZodOptional<z.ZodString>;
|
|
43
43
|
}, "strict", z.ZodTypeAny, {
|
|
44
|
-
buildTarget?: string | undefined;
|
|
45
|
-
port?: string | undefined;
|
|
46
44
|
board?: string | undefined;
|
|
45
|
+
port?: string | undefined;
|
|
46
|
+
buildTarget?: string | undefined;
|
|
47
47
|
baudRate?: number | undefined;
|
|
48
48
|
include?: string[] | undefined;
|
|
49
49
|
timeout?: number | undefined;
|
|
50
50
|
}, {
|
|
51
|
-
buildTarget?: string | undefined;
|
|
52
|
-
port?: string | undefined;
|
|
53
51
|
board?: string | undefined;
|
|
52
|
+
port?: string | undefined;
|
|
53
|
+
buildTarget?: string | undefined;
|
|
54
54
|
baudRate?: number | undefined;
|
|
55
55
|
include?: string[] | undefined;
|
|
56
56
|
timeout?: number | undefined;
|
|
@@ -83,6 +83,12 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
83
83
|
} | undefined;
|
|
84
84
|
frameworkData?: Record<string, unknown> | undefined;
|
|
85
85
|
target?: string | undefined;
|
|
86
|
+
board?: string | undefined;
|
|
87
|
+
exclude?: string[] | undefined;
|
|
88
|
+
toolchain?: {
|
|
89
|
+
type?: string | undefined;
|
|
90
|
+
frameworkOptions?: Record<string, unknown> | undefined;
|
|
91
|
+
} | undefined;
|
|
86
92
|
framework?: string | undefined;
|
|
87
93
|
native?: Record<string, unknown> | undefined;
|
|
88
94
|
output?: {
|
|
@@ -92,20 +98,14 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
92
98
|
defines?: Record<string, string> | undefined;
|
|
93
99
|
extraFlags?: string[] | undefined;
|
|
94
100
|
} | undefined;
|
|
95
|
-
board?: string | undefined;
|
|
96
101
|
mcu?: string | undefined;
|
|
97
102
|
include?: string[] | undefined;
|
|
98
103
|
entry?: string | undefined;
|
|
99
|
-
toolchain?: {
|
|
100
|
-
type?: string | undefined;
|
|
101
|
-
frameworkOptions?: Record<string, unknown> | undefined;
|
|
102
|
-
} | undefined;
|
|
103
104
|
contract?: string | undefined;
|
|
104
|
-
exclude?: string[] | undefined;
|
|
105
105
|
test?: {
|
|
106
|
-
buildTarget?: string | undefined;
|
|
107
|
-
port?: string | undefined;
|
|
108
106
|
board?: string | undefined;
|
|
107
|
+
port?: string | undefined;
|
|
108
|
+
buildTarget?: string | undefined;
|
|
109
109
|
baudRate?: number | undefined;
|
|
110
110
|
include?: string[] | undefined;
|
|
111
111
|
timeout?: number | undefined;
|
|
@@ -117,6 +117,12 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
117
117
|
} | undefined;
|
|
118
118
|
frameworkData?: Record<string, unknown> | undefined;
|
|
119
119
|
target?: string | undefined;
|
|
120
|
+
board?: string | undefined;
|
|
121
|
+
exclude?: string[] | undefined;
|
|
122
|
+
toolchain?: {
|
|
123
|
+
type?: string | undefined;
|
|
124
|
+
frameworkOptions?: Record<string, unknown> | undefined;
|
|
125
|
+
} | undefined;
|
|
120
126
|
framework?: string | undefined;
|
|
121
127
|
native?: Record<string, unknown> | undefined;
|
|
122
128
|
output?: {
|
|
@@ -126,20 +132,14 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
126
132
|
defines?: Record<string, string> | undefined;
|
|
127
133
|
extraFlags?: string[] | undefined;
|
|
128
134
|
} | undefined;
|
|
129
|
-
board?: string | undefined;
|
|
130
135
|
mcu?: string | undefined;
|
|
131
136
|
include?: string[] | undefined;
|
|
132
137
|
entry?: string | undefined;
|
|
133
|
-
toolchain?: {
|
|
134
|
-
type?: string | undefined;
|
|
135
|
-
frameworkOptions?: Record<string, unknown> | undefined;
|
|
136
|
-
} | undefined;
|
|
137
138
|
contract?: string | undefined;
|
|
138
|
-
exclude?: string[] | undefined;
|
|
139
139
|
test?: {
|
|
140
|
-
buildTarget?: string | undefined;
|
|
141
|
-
port?: string | undefined;
|
|
142
140
|
board?: string | undefined;
|
|
141
|
+
port?: string | undefined;
|
|
142
|
+
buildTarget?: string | undefined;
|
|
143
143
|
baudRate?: number | undefined;
|
|
144
144
|
include?: string[] | undefined;
|
|
145
145
|
timeout?: number | undefined;
|
|
@@ -151,6 +151,12 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
151
151
|
} | undefined;
|
|
152
152
|
frameworkData?: Record<string, unknown> | undefined;
|
|
153
153
|
target?: string | undefined;
|
|
154
|
+
board?: string | undefined;
|
|
155
|
+
exclude?: string[] | undefined;
|
|
156
|
+
toolchain?: {
|
|
157
|
+
type?: string | undefined;
|
|
158
|
+
frameworkOptions?: Record<string, unknown> | undefined;
|
|
159
|
+
} | undefined;
|
|
154
160
|
framework?: string | undefined;
|
|
155
161
|
native?: Record<string, unknown> | undefined;
|
|
156
162
|
output?: {
|
|
@@ -160,20 +166,14 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
160
166
|
defines?: Record<string, string> | undefined;
|
|
161
167
|
extraFlags?: string[] | undefined;
|
|
162
168
|
} | undefined;
|
|
163
|
-
board?: string | undefined;
|
|
164
169
|
mcu?: string | undefined;
|
|
165
170
|
include?: string[] | undefined;
|
|
166
171
|
entry?: string | undefined;
|
|
167
|
-
toolchain?: {
|
|
168
|
-
type?: string | undefined;
|
|
169
|
-
frameworkOptions?: Record<string, unknown> | undefined;
|
|
170
|
-
} | undefined;
|
|
171
172
|
contract?: string | undefined;
|
|
172
|
-
exclude?: string[] | undefined;
|
|
173
173
|
test?: {
|
|
174
|
-
buildTarget?: string | undefined;
|
|
175
|
-
port?: string | undefined;
|
|
176
174
|
board?: string | undefined;
|
|
175
|
+
port?: string | undefined;
|
|
176
|
+
buildTarget?: string | undefined;
|
|
177
177
|
baudRate?: number | undefined;
|
|
178
178
|
include?: string[] | undefined;
|
|
179
179
|
timeout?: number | undefined;
|
|
@@ -185,6 +185,12 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
185
185
|
} | undefined;
|
|
186
186
|
frameworkData?: Record<string, unknown> | undefined;
|
|
187
187
|
target?: string | undefined;
|
|
188
|
+
board?: string | undefined;
|
|
189
|
+
exclude?: string[] | undefined;
|
|
190
|
+
toolchain?: {
|
|
191
|
+
type?: string | undefined;
|
|
192
|
+
frameworkOptions?: Record<string, unknown> | undefined;
|
|
193
|
+
} | undefined;
|
|
188
194
|
framework?: string | undefined;
|
|
189
195
|
native?: Record<string, unknown> | undefined;
|
|
190
196
|
output?: {
|
|
@@ -194,20 +200,14 @@ export declare const CuttlefishConfigSchema: z.ZodEffects<z.ZodObject<{
|
|
|
194
200
|
defines?: Record<string, string> | undefined;
|
|
195
201
|
extraFlags?: string[] | undefined;
|
|
196
202
|
} | undefined;
|
|
197
|
-
board?: string | undefined;
|
|
198
203
|
mcu?: string | undefined;
|
|
199
204
|
include?: string[] | undefined;
|
|
200
205
|
entry?: string | undefined;
|
|
201
|
-
toolchain?: {
|
|
202
|
-
type?: string | undefined;
|
|
203
|
-
frameworkOptions?: Record<string, unknown> | undefined;
|
|
204
|
-
} | undefined;
|
|
205
206
|
contract?: string | undefined;
|
|
206
|
-
exclude?: string[] | undefined;
|
|
207
207
|
test?: {
|
|
208
|
-
buildTarget?: string | undefined;
|
|
209
|
-
port?: string | undefined;
|
|
210
208
|
board?: string | undefined;
|
|
209
|
+
port?: string | undefined;
|
|
210
|
+
buildTarget?: string | undefined;
|
|
211
211
|
baudRate?: number | undefined;
|
|
212
212
|
include?: string[] | undefined;
|
|
213
213
|
timeout?: number | undefined;
|
|
@@ -40,6 +40,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
40
40
|
}, "strict", z.ZodTypeAny, {
|
|
41
41
|
gpio: number;
|
|
42
42
|
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
43
|
+
notes?: string | undefined;
|
|
43
44
|
functions?: {
|
|
44
45
|
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
45
46
|
instance: number;
|
|
@@ -48,11 +49,11 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
48
49
|
alt?: string[] | undefined;
|
|
49
50
|
warnings?: string[] | undefined;
|
|
50
51
|
unsafe?: boolean | undefined;
|
|
51
|
-
notes?: string | undefined;
|
|
52
52
|
onboardLed?: boolean | undefined;
|
|
53
53
|
}, {
|
|
54
54
|
gpio: number;
|
|
55
55
|
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
56
|
+
notes?: string | undefined;
|
|
56
57
|
functions?: {
|
|
57
58
|
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
58
59
|
instance: number;
|
|
@@ -61,7 +62,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
61
62
|
alt?: string[] | undefined;
|
|
62
63
|
warnings?: string[] | undefined;
|
|
63
64
|
unsafe?: boolean | undefined;
|
|
64
|
-
notes?: string | undefined;
|
|
65
65
|
onboardLed?: boolean | undefined;
|
|
66
66
|
}>, "many">;
|
|
67
67
|
unsafe: z.ZodArray<z.ZodString, "many">;
|
|
@@ -436,6 +436,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
436
436
|
pins: {
|
|
437
437
|
gpio: number;
|
|
438
438
|
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
439
|
+
notes?: string | undefined;
|
|
439
440
|
functions?: {
|
|
440
441
|
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
441
442
|
instance: number;
|
|
@@ -444,7 +445,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
444
445
|
alt?: string[] | undefined;
|
|
445
446
|
warnings?: string[] | undefined;
|
|
446
447
|
unsafe?: boolean | undefined;
|
|
447
|
-
notes?: string | undefined;
|
|
448
448
|
onboardLed?: boolean | undefined;
|
|
449
449
|
}[];
|
|
450
450
|
analog: string[];
|
|
@@ -568,6 +568,7 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
568
568
|
pins: {
|
|
569
569
|
gpio: number;
|
|
570
570
|
capabilities: "FULL_GPIO" | "FULL_GPIO_ANALOG" | "FULL_GPIO_TOUCH" | "FULL_GPIO_ANALOG_TOUCH" | "FULL_GPIO_DAC" | "INPUT_ONLY";
|
|
571
|
+
notes?: string | undefined;
|
|
571
572
|
functions?: {
|
|
572
573
|
type: "i2c" | "spi" | "uart" | "adc" | "dac" | "pwm" | "touch" | "usb";
|
|
573
574
|
instance: number;
|
|
@@ -576,7 +577,6 @@ export declare const BoardSpecSchema: z.ZodObject<{
|
|
|
576
577
|
alt?: string[] | undefined;
|
|
577
578
|
warnings?: string[] | undefined;
|
|
578
579
|
unsafe?: boolean | undefined;
|
|
579
|
-
notes?: string | undefined;
|
|
580
580
|
onboardLed?: boolean | undefined;
|
|
581
581
|
}[];
|
|
582
582
|
analog: string[];
|
package/dist/create/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget, printInitNextSteps } from './init-scaffold.js';
|
|
2
2
|
export type { KnownTarget, KnownBoard, ScaffoldProjectResult } from './init-scaffold.js';
|
|
3
|
-
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateGitignore, generateEslintConfig, } from './init-templates.js';
|
|
3
|
+
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, } from './init-templates.js';
|
|
4
4
|
export type { InitProjectOptions } from './init-templates.js';
|
|
5
5
|
export { runInitWizard } from './init-wizard.js';
|
|
6
6
|
export { scaffoldBoardPackages } from './board-codegen.js';
|
package/dist/create/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget, printInitNextSteps } from './init-scaffold.js';
|
|
2
|
-
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateGitignore, generateEslintConfig, } from './init-templates.js';
|
|
2
|
+
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, } from './init-templates.js';
|
|
3
3
|
export { runInitWizard } from './init-wizard.js';
|
|
4
4
|
// Board codegen tool (`cuttlefish board add`)
|
|
5
5
|
export { scaffoldBoardPackages } from './board-codegen.js';
|
|
@@ -10,6 +10,9 @@ export interface KnownTarget {
|
|
|
10
10
|
framework: string;
|
|
11
11
|
buildTarget?: string;
|
|
12
12
|
mcu?: string;
|
|
13
|
+
/** Framework-specific config (becomes frameworkData in cuttlefish.config.ts).
|
|
14
|
+
* Used by framework-esp32 to carry `target: 'esp32'|'esp32s3'|'esp32c3'|'esp32c6'`. */
|
|
15
|
+
frameworkData?: Record<string, unknown>;
|
|
13
16
|
}
|
|
14
17
|
export declare function registerKnownTarget(target: KnownTarget): void;
|
|
15
18
|
export declare const KNOWN_TARGETS: ReadonlyArray<KnownTarget>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
-
import { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateGitignore, generateBoardForwardingFile, generateEslintConfig, } from "./init-templates.js";
|
|
4
|
+
import { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateBoardForwardingFile, generateEslintConfig, } from "./init-templates.js";
|
|
5
5
|
import { generateEslintRules } from "./eslint-rules-template.js";
|
|
6
6
|
const _knownTargets = [
|
|
7
7
|
{
|
|
@@ -33,6 +33,18 @@ const _knownTargets = [
|
|
|
33
33
|
buildTarget: 'esp32:esp32:esp32',
|
|
34
34
|
mcu: 'esp32',
|
|
35
35
|
},
|
|
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
|
+
},
|
|
36
48
|
{
|
|
37
49
|
id: 'esp32s3',
|
|
38
50
|
displayName: 'ESP32-S3',
|
|
@@ -44,6 +56,18 @@ const _knownTargets = [
|
|
|
44
56
|
buildTarget: 'esp32:esp32:esp32s3',
|
|
45
57
|
mcu: 'esp32s3',
|
|
46
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
|
+
buildTarget: 'esp32:esp32:esp32s3',
|
|
68
|
+
mcu: 'esp32s3',
|
|
69
|
+
frameworkData: { target: 'esp32s3' },
|
|
70
|
+
},
|
|
47
71
|
{
|
|
48
72
|
id: 'esp32c3',
|
|
49
73
|
displayName: 'ESP32-C3',
|
|
@@ -55,6 +79,18 @@ const _knownTargets = [
|
|
|
55
79
|
buildTarget: 'esp32:esp32:esp32c3',
|
|
56
80
|
mcu: 'esp32c3',
|
|
57
81
|
},
|
|
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
|
+
},
|
|
58
94
|
{
|
|
59
95
|
id: 'esp32c6',
|
|
60
96
|
displayName: 'ESP32-C6',
|
|
@@ -66,6 +102,18 @@ const _knownTargets = [
|
|
|
66
102
|
buildTarget: 'esp32:esp32:esp32c6',
|
|
67
103
|
mcu: 'esp32c6',
|
|
68
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
|
+
buildTarget: 'esp32:esp32:esp32c6',
|
|
114
|
+
mcu: 'esp32c6',
|
|
115
|
+
frameworkData: { target: 'esp32c6' },
|
|
116
|
+
},
|
|
69
117
|
{
|
|
70
118
|
id: 'rp2040',
|
|
71
119
|
displayName: 'RP2040 (Pico)',
|
|
@@ -150,6 +198,24 @@ export function scaffoldProject(options, outDir) {
|
|
|
150
198
|
fs.writeFileSync(sketchPath, generateStarterSketch(options), 'utf-8');
|
|
151
199
|
createdFiles.push(sketchPath);
|
|
152
200
|
}
|
|
201
|
+
// Embedded projects get a starter hardware test (@typecad/expect / cuttlefish-test).
|
|
202
|
+
// Native projects have no serial/board path, so they get no test setup.
|
|
203
|
+
if (!options.isNative) {
|
|
204
|
+
const testsDir = path.join(resolvedOutDir, 'tests');
|
|
205
|
+
fs.mkdirSync(testsDir, { recursive: true });
|
|
206
|
+
const testPath = path.join(testsDir, '01-basics.test.ts');
|
|
207
|
+
fs.writeFileSync(testPath, generateStarterTest(options), 'utf-8');
|
|
208
|
+
createdFiles.push(testPath);
|
|
209
|
+
// Host-side simulation (@typecad/simulator + vitest). sim/ is kept separate
|
|
210
|
+
// from tests/ so `vitest run sim/` never loads the @typecad/expect no-op
|
|
211
|
+
// stubs, and `cuttlefish-test` (which globs tests/) never tries to flash a
|
|
212
|
+
// simulator file as firmware.
|
|
213
|
+
const simDir = path.join(resolvedOutDir, 'sim');
|
|
214
|
+
fs.mkdirSync(simDir, { recursive: true });
|
|
215
|
+
const simPath = path.join(simDir, 'main.test.ts');
|
|
216
|
+
fs.writeFileSync(simPath, generateStarterSim(options), 'utf-8');
|
|
217
|
+
createdFiles.push(simPath);
|
|
218
|
+
}
|
|
153
219
|
return { createdFiles, outDir: resolvedOutDir, options };
|
|
154
220
|
}
|
|
155
221
|
export function printInitNextSteps(options, outDir) {
|
|
@@ -164,9 +230,15 @@ export function printInitNextSteps(options, outDir) {
|
|
|
164
230
|
if (!options.isNative) {
|
|
165
231
|
const portHint = process.platform === 'win32' ? 'COM4' : '/dev/ttyACM0';
|
|
166
232
|
console.log();
|
|
233
|
+
console.log(chalk.bold.white("To simulate without hardware:"));
|
|
234
|
+
console.log(` ${chalk.cyan("npm run simulate")}`);
|
|
235
|
+
console.log();
|
|
167
236
|
console.log(chalk.bold.white("To upload to your board:"));
|
|
168
237
|
console.log(` ${chalk.cyan("npm run upload")}`);
|
|
169
238
|
console.log();
|
|
170
|
-
console.log(chalk.
|
|
239
|
+
console.log(chalk.bold.white("To run hardware tests:"));
|
|
240
|
+
console.log(` ${chalk.cyan("npm run test:hw")}`);
|
|
241
|
+
console.log();
|
|
242
|
+
console.log(chalk.dim(`Edit ${chalk.white("cuttlefish.config.ts")} to change the serial port from ${chalk.white(portHint)} to your port.`));
|
|
171
243
|
}
|
|
172
244
|
}
|