@typecad/cuttlefish 0.1.0-alpha.2 → 1.0.0-alpha.3
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 +6 -6
- package/dist/api/board-types.d.ts +1 -1
- package/dist/api/shared/platform-strategy.d.ts +6 -0
- package/dist/cli.js +9 -0
- package/dist/create/init-scaffold.js +22 -0
- package/dist/emit/emitters/setup.js +7 -1
- package/dist/transpile.js +11 -4
- package/dist/types.d.ts +2 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
TypeScript → C++ transpiler for embedded firmware. Targets native (desktop),
|
|
4
4
|
Arduino, and bare-metal MCU builds from a single TypeScript codebase.
|
|
5
5
|
|
|
6
|
-
`cuttlefish` is the command-line tool at the center of the [TypeCAD](https://
|
|
6
|
+
`cuttlefish` is the command-line tool at the center of the [TypeCAD](https://cuttlefish.typecad.net)
|
|
7
7
|
toolchain: it loads `cuttlefish.config.ts`, transpiles TypeScript firmware to
|
|
8
8
|
C++, and can chain compile, upload, and serial-monitor steps.
|
|
9
9
|
|
|
@@ -67,11 +67,11 @@ export default config;
|
|
|
67
67
|
|
|
68
68
|
`@typecad/cuttlefish` is the transpiler core. It pairs with sibling packages:
|
|
69
69
|
|
|
70
|
-
- [`@typecad/hal`](https://
|
|
71
|
-
- [`@typecad/ui`](https://
|
|
72
|
-
- [`@typecad/expect`](https://
|
|
73
|
-
- [`@typecad/framework-arduino`](https://
|
|
74
|
-
- [`@typecad/framework-native`](https://
|
|
70
|
+
- [`@typecad/hal`](https://cuttlefish.typecad.net) — hardware abstraction (GPIO, I2C, SPI, UART) as regular TypeScript.
|
|
71
|
+
- [`@typecad/ui`](https://cuttlefish.typecad.net) — HTML/CSS-driven graphics for microcontroller displays.
|
|
72
|
+
- [`@typecad/expect`](https://cuttlefish.typecad.net) — hardware test framework (vitest-style assertions over serial).
|
|
73
|
+
- [`@typecad/framework-arduino`](https://cuttlefish.typecad.net) — Arduino framework code-gen strategy.
|
|
74
|
+
- [`@typecad/framework-native`](https://cuttlefish.typecad.net) — native desktop C++ code-gen strategy.
|
|
75
75
|
- `@typecad/mcu-*` and `@typecad/board-*` — silicon- and board-level pin/peripheral definitions.
|
|
76
76
|
|
|
77
77
|
## License
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type ArchitectureIdentifier = 'avr' | 'esp32' | 'esp32s2' | 'esp32s3' | 'esp32c3' | 'esp32c6' | 'rp2040' | 'samd' | 'stm32' | 'nrf52' | (string & {});
|
|
1
|
+
export type ArchitectureIdentifier = 'avr' | 'esp32' | 'esp32s2' | 'esp32s3' | 'esp32c3' | 'esp32c6' | 'rp2040' | 'rp2350' | 'samd' | 'stm32' | 'nrf52' | (string & {});
|
|
@@ -8,6 +8,12 @@ import type { PlatformGraphicsStrategy } from './graphics-strategy.js';
|
|
|
8
8
|
export interface PlatformProfileStrategy {
|
|
9
9
|
/** System #include headers forced at the top of every emitted file. */
|
|
10
10
|
forcedIncludes(program: ProgramIR, ctx?: PlatformContext): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Filter the HAL-discovered required includes (from __includes metadata).
|
|
13
|
+
* Frameworks that provide native peripheral drivers can strip stale Arduino
|
|
14
|
+
* library includes here. Defaults to returning the includes unchanged.
|
|
15
|
+
*/
|
|
16
|
+
filterRequiredIncludes?(includes: string[]): string[];
|
|
11
17
|
/** Symbol aliases (TypeScript name → C++ name). */
|
|
12
18
|
symbolAliases(program: ProgramIR, ctx?: PlatformContext): Record<string, string>;
|
|
13
19
|
/** Extra shim lines emitted after includes (e.g. #define fallbacks). */
|
package/dist/cli.js
CHANGED
|
@@ -361,6 +361,9 @@ async function main() {
|
|
|
361
361
|
});
|
|
362
362
|
printDiagnostics(result.diagnostics);
|
|
363
363
|
ui.printTasks(result.asyncTaskNames ?? [], result.usesTimers ?? false);
|
|
364
|
+
if (result.diagnosticsReportPath) {
|
|
365
|
+
ui.printInfo(`Diagnostics report: ${result.diagnosticsReportPath}`);
|
|
366
|
+
}
|
|
364
367
|
if (result.diagnostics.length === 0) {
|
|
365
368
|
ui.printSuccess();
|
|
366
369
|
initialBuildOk = true;
|
|
@@ -451,6 +454,9 @@ async function main() {
|
|
|
451
454
|
});
|
|
452
455
|
printDiagnostics(rebuildResult.diagnostics);
|
|
453
456
|
ui.printTasks(rebuildResult.asyncTaskNames ?? [], rebuildResult.usesTimers ?? false);
|
|
457
|
+
if (rebuildResult.diagnosticsReportPath) {
|
|
458
|
+
ui.printInfo(`Diagnostics report: ${rebuildResult.diagnosticsReportPath}`);
|
|
459
|
+
}
|
|
454
460
|
if (rebuildResult.diagnostics.length > 0) {
|
|
455
461
|
// Errors shown via printDiagnostics — skip compile/upload
|
|
456
462
|
}
|
|
@@ -535,6 +541,9 @@ async function main() {
|
|
|
535
541
|
});
|
|
536
542
|
printDiagnostics(result.diagnostics);
|
|
537
543
|
ui.printTasks(result.asyncTaskNames ?? [], result.usesTimers ?? false);
|
|
544
|
+
if (result.diagnosticsReportPath) {
|
|
545
|
+
ui.printInfo(`Diagnostics report: ${result.diagnosticsReportPath}`);
|
|
546
|
+
}
|
|
538
547
|
}
|
|
539
548
|
if (hasFatalDiagnostics(result)) {
|
|
540
549
|
ui.printError("Transpilation failed. Fix the transpiler diagnostics above before compiling.");
|
|
@@ -66,6 +66,28 @@ const _knownTargets = [
|
|
|
66
66
|
buildTarget: 'esp32:esp32:esp32c6',
|
|
67
67
|
mcu: 'esp32c6',
|
|
68
68
|
},
|
|
69
|
+
{
|
|
70
|
+
id: 'rp2040',
|
|
71
|
+
displayName: 'RP2040 (Pico)',
|
|
72
|
+
isNative: false,
|
|
73
|
+
architecture: 'rp2040',
|
|
74
|
+
boardPackage: '@typecad/board-rp2040',
|
|
75
|
+
frameworkPackage: '@typecad/framework-arduino',
|
|
76
|
+
framework: 'arduino',
|
|
77
|
+
buildTarget: 'rp2040:rp2040:rpipico',
|
|
78
|
+
mcu: 'rp2040',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'rp2350',
|
|
82
|
+
displayName: 'RP2350 (Pico 2)',
|
|
83
|
+
isNative: false,
|
|
84
|
+
architecture: 'rp2350',
|
|
85
|
+
boardPackage: '@typecad/board-rp2350',
|
|
86
|
+
frameworkPackage: '@typecad/framework-arduino',
|
|
87
|
+
framework: 'arduino',
|
|
88
|
+
buildTarget: 'rp2040:rp2040:rpipico2',
|
|
89
|
+
mcu: 'rp2350',
|
|
90
|
+
},
|
|
69
91
|
];
|
|
70
92
|
export function registerKnownTarget(target) {
|
|
71
93
|
const existing = _knownTargets.findIndex(t => t.id === target.id);
|
|
@@ -715,7 +715,13 @@ export function buildEmitterContext(program, options) {
|
|
|
715
715
|
includes.push(...emittedPolyfills.includes.map((include) => normalizeInclude(include)));
|
|
716
716
|
}
|
|
717
717
|
if (program.requiredIncludes) {
|
|
718
|
-
|
|
718
|
+
let reqIncludes = [...program.requiredIncludes];
|
|
719
|
+
// Let the strategy strip stale includes (e.g. framework-avr removes
|
|
720
|
+
// Arduino library headers it doesn't need — Wire.h, SPI.h, etc.).
|
|
721
|
+
if (strategy.filterRequiredIncludes) {
|
|
722
|
+
reqIncludes = strategy.filterRequiredIncludes(reqIncludes);
|
|
723
|
+
}
|
|
724
|
+
includes.push(...reqIncludes);
|
|
719
725
|
}
|
|
720
726
|
// UI text bindings lower to snprintf bodies that need <stdio.h>. Pushed here
|
|
721
727
|
// (in buildEmitterContext) rather than in emitUIRuntime because emitPreamble
|
package/dist/transpile.js
CHANGED
|
@@ -689,6 +689,7 @@ export async function transpileFile(options) {
|
|
|
689
689
|
profiler.endTimer("post:flatten");
|
|
690
690
|
// Profiler session ends (profiling disabled - no report generation)
|
|
691
691
|
// ── Generate diagnostics report if enabled ──────────────────────────────
|
|
692
|
+
let diagnosticsReportPath;
|
|
692
693
|
if (options.diagnostics) {
|
|
693
694
|
try {
|
|
694
695
|
const entryPreBuilt = preBuilt.get(entryFile);
|
|
@@ -708,17 +709,23 @@ export async function transpileFile(options) {
|
|
|
708
709
|
removedSymbols: allRemovedSymbols,
|
|
709
710
|
});
|
|
710
711
|
writeDiagnosticsReport(report, entryPreBuilt?.programIR ?? null, outDir);
|
|
712
|
+
diagnosticsReportPath = path.join(outDir, "diagnostics.md");
|
|
711
713
|
}
|
|
712
714
|
catch (e) {
|
|
713
|
-
// Diagnostics report generation is best-effort; don't fail the build
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
715
|
+
// Diagnostics report generation is best-effort; don't fail the build,
|
|
716
|
+
// but surface the failure so the user knows --diagnostics didn't work.
|
|
717
|
+
diagnostics.push({
|
|
718
|
+
severity: "warning",
|
|
719
|
+
message: `Diagnostics report generation failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
720
|
+
code: "diagnostics-report-failed",
|
|
721
|
+
source: "transpile",
|
|
722
|
+
});
|
|
717
723
|
}
|
|
718
724
|
}
|
|
719
725
|
return {
|
|
720
726
|
...entryOutputs,
|
|
721
727
|
diagnostics,
|
|
728
|
+
diagnosticsReportPath,
|
|
722
729
|
};
|
|
723
730
|
}
|
|
724
731
|
export function generateLibraryDefinitions(options) {
|
package/dist/types.d.ts
CHANGED
|
@@ -181,6 +181,8 @@ export interface GeneratedOutputs {
|
|
|
181
181
|
diagnostics: Diagnostic[];
|
|
182
182
|
asyncTaskNames?: string[];
|
|
183
183
|
usesTimers?: boolean;
|
|
184
|
+
/** Path to the diagnostics.md report, if --diagnostics was passed. */
|
|
185
|
+
diagnosticsReportPath?: string;
|
|
184
186
|
}
|
|
185
187
|
interface CompileErrorEntry {
|
|
186
188
|
filePath: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typecad/cuttlefish",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "TypeScript to C++ transpiler — native, Arduino, and bare-metal targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/transpile.js",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"zod": "^3.24.0"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
|
-
"@typecad/ui": "
|
|
86
|
+
"@typecad/ui": "1.0.0-alpha.3"
|
|
87
87
|
},
|
|
88
88
|
"peerDependenciesMeta": {
|
|
89
89
|
"@typecad/ui": {
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
93
|
"optionalDependencies": {
|
|
94
|
-
"@typecad/framework-native": "
|
|
94
|
+
"@typecad/framework-native": "1.0.0-alpha.3"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@types/node": "^22.10.7"
|