@typecad/cuttlefish 1.0.0-alpha.13 → 1.0.0-alpha.15
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 +82 -79
- package/assets/editor-extensions/typecad-debug/README.md +141 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
- package/assets/editor-extensions/typecad-debug/package.json +76 -0
- package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
- package/assets/editor-extensions/typecad-ui/README.md +52 -0
- package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
- package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
- package/assets/editor-extensions/typecad-ui/icon.png +0 -0
- package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
- package/assets/editor-extensions/typecad-ui/package.json +54 -0
- package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
- package/dist/api/config.d.ts +30 -27
- package/dist/api/schema/types.d.ts +20 -3
- package/dist/api/shared/async-runtime-static.d.ts +1 -1
- package/dist/api/shared/async-runtime-static.js +5 -5
- package/dist/api/shared/async-types.d.ts +3 -2
- package/dist/api/shared/board-catalog.d.ts +2 -0
- package/dist/api/shared/board-catalog.js +6 -0
- package/dist/api/shared/board-resolver.d.ts +4 -7
- package/dist/api/shared/board-resolver.js +2 -1
- package/dist/api/shared/coop-scheduler.d.ts +1 -1
- package/dist/api/shared/coop-scheduler.js +1 -1
- package/dist/api/shared/cpp-type-ir.d.ts +1 -1
- package/dist/api/shared/cpp-type-ir.js +1 -1
- package/dist/api/shared/display-profile.d.ts +1 -1
- package/dist/api/shared/display-profile.js +3 -5
- package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
- package/dist/api/shared/framework-manifest-registry.js +0 -1
- package/dist/api/shared/framework-manifest.d.ts +65 -507
- package/dist/api/shared/framework-manifest.js +6 -11
- package/dist/api/shared/hal-op-ir.d.ts +294 -685
- package/dist/api/shared/hal-op-ir.js +31 -65
- package/dist/api/shared/index.d.ts +0 -4
- package/dist/api/shared/index.js +1 -7
- package/dist/api/shared/ir-core.d.ts +6 -0
- package/dist/api/shared/ir-declarations.d.ts +4 -0
- package/dist/api/shared/ir.d.ts +1 -3
- package/dist/api/shared/platform-strategy.d.ts +14 -37
- package/dist/api/shared/polyfill-helper-registry.js +0 -5
- package/dist/api/shared/polyfill-types.js +0 -27
- package/dist/api/shared/promise-runtime.js +3 -3
- package/dist/api/shared/spdx-licenses.d.ts +12 -10
- package/dist/api/shared/spdx-licenses.js +1 -1
- package/dist/api/shared/toolchain-types.d.ts +1 -1
- package/dist/api/shared/toolchain-types.js +3 -3
- package/dist/api/shared/types.d.ts +0 -3
- package/dist/api/shared/validate-framework-manifest.js +13 -33
- package/dist/board-catalog/dts-reader.d.ts +220 -0
- package/dist/board-catalog/dts-reader.js +1052 -0
- package/dist/board-catalog/index.d.ts +11 -0
- package/dist/board-catalog/index.js +12 -0
- package/dist/board-catalog/pinconfig.d.ts +48 -0
- package/dist/board-catalog/pinconfig.js +263 -0
- package/dist/board-catalog/sdk.d.ts +82 -0
- package/dist/board-catalog/sdk.js +180 -0
- package/dist/board-catalog/store.d.ts +196 -0
- package/dist/board-catalog/store.js +363 -0
- package/dist/board-catalog/types.d.ts +233 -0
- package/dist/board-catalog/types.js +7 -0
- package/dist/board-catalog/walker.d.ts +112 -0
- package/dist/board-catalog/walker.js +1101 -0
- package/dist/cli-utils.d.ts +2 -2
- package/dist/cli-utils.js +5 -5
- package/dist/cli.js +227 -244
- package/dist/config-loader.d.ts +14 -19
- package/dist/config-loader.js +242 -78
- package/dist/config-schema.d.ts +19 -227
- package/dist/config-schema.js +9 -8
- package/dist/contract/board-generator.d.ts +4 -4
- package/dist/contract/board-generator.js +16 -5
- package/dist/contract/contract-parser.d.ts +36 -127
- package/dist/contract/contract-parser.js +76 -0
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.js +70 -21
- package/dist/create/active-board-catalog.d.ts +9 -0
- package/dist/create/active-board-catalog.js +94 -0
- package/dist/create/board-catalog.generated.d.ts +96 -0
- package/dist/create/board-catalog.generated.js +128737 -0
- package/dist/create/board-search.d.ts +23 -0
- package/dist/create/board-search.js +88 -0
- package/dist/create/editor-integration.d.ts +32 -0
- package/dist/create/editor-integration.js +257 -0
- package/dist/create/eslint-rules-template.d.ts +2 -2
- package/dist/create/framework-catalog.d.ts +48 -8
- package/dist/create/framework-catalog.js +58 -44
- package/dist/create/index.d.ts +8 -13
- package/dist/create/index.js +5 -9
- package/dist/create/mcu-target.d.ts +39 -0
- package/dist/create/mcu-target.js +80 -0
- package/dist/create/pack-targets.d.ts +19 -0
- package/dist/create/pack-targets.js +56 -0
- package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +8 -11
- package/dist/create/{init-scaffold.js → scaffold.js} +28 -87
- package/dist/create/templates.d.ts +51 -0
- package/dist/create/{init-templates.js → templates.js} +135 -116
- package/dist/create/wizard.d.ts +19 -0
- package/dist/create/wizard.js +314 -0
- package/dist/debug/preprocessor.d.ts +5 -0
- package/dist/debug/preprocessor.js +31 -7
- package/dist/diagnostics/diagnostics-report.d.ts +1 -1
- package/dist/diagnostics/diagnostics-report.js +3 -11
- package/dist/diagnostics/json-schema.d.ts +1 -1
- package/dist/diagnostics/md-writer.js +2 -2
- package/dist/diagnostics/mermaid-builder.d.ts +1 -1
- package/dist/diagnostics/mermaid-builder.js +1 -1
- package/dist/emit/cpp-emitter.js +4 -1
- package/dist/emit/emitters/class-emitter.js +32 -4
- package/dist/emit/emitters/emitter-context.d.ts +11 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
- package/dist/emit/emitters/function-emitter-impl.js +33 -17
- package/dist/emit/emitters/output-finalizer.d.ts +7 -0
- package/dist/emit/emitters/output-finalizer.js +31 -23
- package/dist/emit/emitters/setup.js +147 -63
- package/dist/emit/emitters/top-level-prep.js +1 -1
- package/dist/emit/emitters/type-decl-emitter.js +13 -8
- package/dist/emit/emitters/ui-emitter.js +1 -1
- package/dist/emit/expression-renderer.d.ts +3 -3
- package/dist/emit/expression-renderer.js +17 -7
- package/dist/emit/route-hal-op.js +17 -48
- package/dist/emit/snprintf-helpers.d.ts +1 -3
- package/dist/emit/snprintf-helpers.js +1 -39
- package/dist/emit/statement-renderer.d.ts +0 -4
- package/dist/emit/statement-renderer.js +54 -45
- package/dist/emit/utils/async-state-machine.d.ts +16 -9
- package/dist/emit/utils/async-state-machine.js +56 -54
- package/dist/emit/utils/comment-helpers.d.ts +0 -8
- package/dist/emit/utils/comment-helpers.js +1 -1
- package/dist/emit/utils/cpp-helpers.d.ts +2 -2
- package/dist/emit/utils/cpp-helpers.js +2 -2
- package/dist/emit/utils/hal-op-cpp-type.js +4 -6
- package/dist/emit/utils/index.d.ts +3 -3
- package/dist/emit/utils/index.js +3 -3
- package/dist/emit/utils/type-inference.d.ts +1 -29
- package/dist/emit/utils/type-inference.js +0 -75
- package/dist/framework-package.d.ts +3 -0
- package/dist/framework-package.js +23 -6
- package/dist/framework-registry.d.ts +5 -5
- package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
- package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
- package/dist/frameworks/native/index.d.ts +3 -0
- package/dist/frameworks/native/index.js +15 -0
- package/dist/frameworks/native/native-compile.d.ts +17 -0
- package/dist/frameworks/native/native-compile.js +170 -0
- package/dist/frameworks/native/native-config.d.ts +41 -0
- package/dist/frameworks/native/native-config.js +7 -0
- package/dist/frameworks/native/strategy.d.ts +97 -0
- package/dist/frameworks/native/strategy.js +664 -0
- package/dist/ir/board-resolver.d.ts +18 -23
- package/dist/ir/board-resolver.js +43 -401
- package/dist/ir/build-ir-state.d.ts +3 -0
- package/dist/ir/build-ir-state.js +42 -0
- package/dist/ir/build-ir.d.ts +1 -1
- package/dist/ir/build-ir.js +64 -45
- package/dist/ir/declaration-builders.js +1 -0
- package/dist/ir/expression-to-ir.js +17 -10
- package/dist/ir/hal/hal-emitter.d.ts +0 -2
- package/dist/ir/hal/hal-emitter.js +92 -41
- package/dist/ir/hal/hal-parser.d.ts +5 -5
- package/dist/ir/hal/hal-parser.js +128 -36
- package/dist/ir/hal/hal-plugins.d.ts +0 -1
- package/dist/ir/hal/hal-plugins.js +425 -716
- package/dist/ir/heap-analysis.js +2 -41
- package/dist/ir/identifier-collector.js +32 -20
- package/dist/ir/network-validation.js +7 -11
- package/dist/ir/ownership-analysis.js +75 -13
- package/dist/ir/peripheral-usage.d.ts +8 -2
- package/dist/ir/peripheral-usage.js +78 -149
- package/dist/ir/peripheral-validation.js +23 -3
- package/dist/ir/pin-capability-validation.d.ts +12 -0
- package/dist/ir/pin-capability-validation.js +61 -97
- package/dist/ir/pin-mode-validation.js +5 -5
- package/dist/ir/program-analysis.d.ts +8 -15
- package/dist/ir/program-analysis.js +140 -323
- package/dist/ir/pulldown-validation.js +11 -4
- package/dist/ir/resource-analysis.js +15 -3
- package/dist/ir/statement-to-ir.js +0 -6
- package/dist/ir/timing-validation.js +1 -1
- package/dist/ir/transformers/array-methods.js +11 -5
- package/dist/ir/transformers/call-statement.js +20 -87
- package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
- package/dist/ir/transformers/callback-context-registry.js +8 -16
- package/dist/ir/transformers/control-flow.js +0 -13
- package/dist/ir/transformers/expressions.js +10 -9
- package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
- package/dist/ir/transformers/hal-call-resolver.js +24 -10
- package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
- package/dist/ir/transformers/hal-emit-helpers.js +2 -2
- package/dist/ir/transformers/namespace-methods.js +1 -1
- package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
- package/dist/ir/transformers/ui-callback-lowering.js +0 -24
- package/dist/ir/transformers/variables.js +338 -42
- package/dist/ir/try-catch-validation.js +4 -3
- package/dist/ir/type-resolution.js +15 -4
- package/dist/ir/validation-orchestrator.js +0 -9
- package/dist/libdef/cpp-to-decl.d.ts +0 -9
- package/dist/libdef/cpp-to-decl.js +0 -72
- package/dist/libdef/registry.d.ts +0 -1
- package/dist/libdef/registry.js +1 -24
- package/dist/library/catalog.d.ts +35 -0
- package/dist/library/catalog.js +67 -0
- package/dist/library/cli.d.ts +2 -0
- package/dist/library/cli.js +168 -0
- package/dist/library/init.d.ts +25 -0
- package/dist/library/init.js +397 -0
- package/dist/library/install.d.ts +9 -0
- package/dist/library/install.js +80 -0
- package/dist/library/registry-search.d.ts +34 -0
- package/dist/library/registry-search.js +50 -0
- package/dist/library/validate.d.ts +17 -0
- package/dist/library/validate.js +175 -0
- package/dist/library-packages.d.ts +95 -0
- package/dist/library-packages.js +275 -0
- package/dist/mapping/peripheral-names.js +9 -4
- package/dist/mapping/source-map.d.ts +3 -4
- package/dist/mapping/source-map.js +12 -18
- package/dist/orchestrator/graph-builder.d.ts +3 -3
- package/dist/orchestrator/graph-builder.js +29 -12
- package/dist/orchestrator/type-checker.d.ts +3 -3
- package/dist/orchestrator/type-checker.js +3 -3
- package/dist/platform/async-runtime.js +1 -1
- package/dist/platform/coop-scheduler-runtime.js +2 -2
- package/dist/platform/generic-debug-codegen.d.ts +36 -0
- package/dist/platform/generic-debug-codegen.js +185 -0
- package/dist/platform/generic-strategy.d.ts +3 -4
- package/dist/platform/generic-strategy.js +5 -80
- package/dist/platform/index.js +1 -1
- package/dist/platform/registry.d.ts +2 -2
- package/dist/platform/registry.js +2 -2
- package/dist/preview/client.js +17 -3
- package/dist/safety/asil-decorators.d.ts +32 -0
- package/dist/safety/asil-decorators.js +32 -0
- package/dist/safety/authoring.d.ts +85 -0
- package/dist/safety/authoring.js +61 -0
- package/dist/safety/engine.d.ts +3 -0
- package/dist/safety/engine.js +83 -0
- package/dist/safety/hal/ops.d.ts +48 -0
- package/dist/safety/hal/ops.js +46 -0
- package/dist/safety/iso26262/analyze.d.ts +13 -0
- package/dist/safety/iso26262/analyze.js +29 -0
- package/dist/safety/iso26262/asil.d.ts +10 -0
- package/dist/safety/iso26262/asil.js +22 -0
- package/dist/safety/iso26262/collect.d.ts +14 -0
- package/dist/safety/iso26262/collect.js +137 -0
- package/dist/safety/iso26262/goto-checker.d.ts +10 -0
- package/dist/safety/iso26262/goto-checker.js +72 -0
- package/dist/safety/iso26262/heap-checker.d.ts +7 -0
- package/dist/safety/iso26262/heap-checker.js +57 -0
- package/dist/safety/iso26262/init-checker.d.ts +13 -0
- package/dist/safety/iso26262/init-checker.js +127 -0
- package/dist/safety/iso26262/loop-checker.d.ts +7 -0
- package/dist/safety/iso26262/loop-checker.js +86 -0
- package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
- package/dist/safety/iso26262/recursion-checker.js +134 -0
- package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
- package/dist/safety/iso26262/sidecar-writer.js +13 -0
- package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
- package/dist/safety/passes/pinMode-intercept.js +60 -0
- package/dist/safety/runtime/mode-table.d.ts +5 -0
- package/dist/safety/runtime/mode-table.js +55 -0
- package/dist/safety/runtime/polyfills.d.ts +6 -0
- package/dist/safety/runtime/polyfills.js +12 -0
- package/dist/safety/runtime/result-struct.d.ts +11 -0
- package/dist/safety/runtime/result-struct.js +98 -0
- package/dist/safety/runtime/safe-int.d.ts +33 -0
- package/dist/safety/runtime/safe-int.js +170 -0
- package/dist/safety/runtime/safe-traits.d.ts +4 -0
- package/dist/safety/runtime/safe-traits.js +95 -0
- package/dist/safety/runtime/safe-variable.d.ts +39 -0
- package/dist/safety/runtime/safe-variable.js +226 -0
- package/dist/safety/runtime/vote.d.ts +8 -0
- package/dist/safety/runtime/vote.js +92 -0
- package/dist/safety/runtime/write-verify.d.ts +8 -0
- package/dist/safety/runtime/write-verify.js +71 -0
- package/dist/safety/safe-int-types.d.ts +45 -0
- package/dist/safety/safe-int-types.js +25 -0
- package/dist/safety/safe-variable-types.d.ts +29 -0
- package/dist/safety/safe-variable-types.js +19 -0
- package/dist/safety/safety-bridge.d.ts +5 -6
- package/dist/safety/safety-bridge.js +15 -28
- package/dist/safety/sidecar-bridge.d.ts +1 -3
- package/dist/safety/sidecar-bridge.js +3 -20
- package/dist/safety/specifiers.d.ts +6 -0
- package/dist/safety/specifiers.js +14 -0
- package/dist/safety-hook.d.ts +8 -7
- package/dist/safety-hook.js +12 -13
- package/dist/testing.d.ts +5 -6
- package/dist/testing.js +5 -5
- package/dist/transpile/resolution.d.ts +1 -1
- package/dist/transpile/resolution.js +18 -9
- package/dist/transpile/test-pins.d.ts +18 -0
- package/dist/transpile/test-pins.js +142 -0
- package/dist/transpile.d.ts +1 -2
- package/dist/transpile.js +90 -29
- package/dist/types.d.ts +45 -26
- package/dist/ui-hook.d.ts +1 -1
- package/dist/utils/cli.d.ts +2 -2
- package/dist/utils/cli.js +160 -157
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +4 -5
- package/dist/utils/strings.d.ts +0 -1
- package/dist/utils/strings.js +0 -8
- package/dist/utils/ui.d.ts +5 -2
- package/dist/utils/ui.js +13 -3
- package/package.json +158 -149
- package/dist/add-preset.d.ts +0 -4
- package/dist/add-preset.js +0 -74
- package/dist/api/shared/async-symbol-detector.d.ts +0 -11
- package/dist/api/shared/async-symbol-detector.js +0 -140
- package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
- package/dist/api/shared/native-display-op-resolver.js +0 -64
- package/dist/create/board-checklist.d.ts +0 -2
- package/dist/create/board-checklist.js +0 -52
- package/dist/create/board-codegen.d.ts +0 -9
- package/dist/create/board-codegen.js +0 -238
- package/dist/create/board-generators.d.ts +0 -12
- package/dist/create/board-generators.js +0 -651
- package/dist/create/board-spec.d.ts +0 -637
- package/dist/create/board-spec.js +0 -214
- package/dist/create/init-templates.d.ts +0 -28
- package/dist/create/init-wizard.d.ts +0 -8
- package/dist/create/init-wizard.js +0 -182
- package/dist/install/framework-catalog.d.ts +0 -53
- package/dist/install/framework-catalog.js +0 -107
- package/dist/install/handle-install.d.ts +0 -35
- package/dist/install/handle-install.js +0 -177
- package/dist/install/index.d.ts +0 -4
- package/dist/install/index.js +0 -3
- package/dist/ir/pin-state-tracking.d.ts +0 -58
- package/dist/ir/pin-state-tracking.js +0 -182
- package/dist/ir/pwm-timer-sharing.d.ts +0 -4
- package/dist/ir/pwm-timer-sharing.js +0 -94
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
- package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
- package/dist/libdef/component-decls.d.ts +0 -2
- package/dist/libdef/component-decls.js +0 -6
- package/dist/libdef/component-discovery.d.ts +0 -43
- package/dist/libdef/component-discovery.js +0 -83
- package/dist/theme-tokens.d.ts +0 -22
- package/dist/theme-tokens.js +0 -172
package/README.md
CHANGED
|
@@ -1,79 +1,82 @@
|
|
|
1
|
-
# `@typecad/cuttlefish`
|
|
2
|
-
|
|
3
|
-
TypeScript → C++ transpiler for embedded firmware. Targets native (desktop)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
`cuttlefish` is the command-line tool at the center of the [TypeCAD](https://cuttlefish.typecad.net)
|
|
7
|
-
toolchain: it loads `cuttlefish.config.ts`, transpiles TypeScript firmware to
|
|
8
|
-
C++, and can chain compile, upload, and serial-monitor steps.
|
|
9
|
-
|
|
10
|
-
## Quick start
|
|
11
|
-
|
|
12
|
-
From a project root containing `cuttlefish.config.ts`:
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npx @typecad/cuttlefish build
|
|
16
|
-
npx @typecad/cuttlefish build --compile --upload --port COM4
|
|
17
|
-
npx @typecad/cuttlefish build --compile --upload --monitor --port COM4 --baud 115200
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Scaffold a starter project with the built-in wizard:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx @typecad/cuttlefish create --board
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Commands
|
|
27
|
-
|
|
28
|
-
| Command | Description |
|
|
29
|
-
| --- | --- |
|
|
30
|
-
| `cuttlefish build` | Transpile the entry file (default). Accepts `--compile`, `--upload`, `--monitor`, `--port`, `--baud`. |
|
|
31
|
-
| `cuttlefish create` | Generate a starter project and `cuttlefish.config.ts`. |
|
|
32
|
-
| `cuttlefish
|
|
33
|
-
| `cuttlefish
|
|
34
|
-
| `cuttlefish
|
|
35
|
-
| `cuttlefish
|
|
36
|
-
| `cuttlefish
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- `--
|
|
43
|
-
- `--
|
|
44
|
-
- `--
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
board: '
|
|
60
|
-
framework: '@typecad/framework-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export default config;
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Ecosystem
|
|
67
|
-
|
|
68
|
-
`@typecad/cuttlefish` is the transpiler core. It pairs with sibling packages:
|
|
69
|
-
|
|
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-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
# `@typecad/cuttlefish`
|
|
2
|
+
|
|
3
|
+
TypeScript → C++ transpiler for embedded firmware. Targets native (desktop)
|
|
4
|
+
and Zephyr-supported embedded boards from a single TypeScript codebase.
|
|
5
|
+
|
|
6
|
+
`cuttlefish` is the command-line tool at the center of the [TypeCAD](https://cuttlefish.typecad.net)
|
|
7
|
+
toolchain: it loads `cuttlefish.config.ts`, transpiles TypeScript firmware to
|
|
8
|
+
C++, and can chain compile, upload, and serial-monitor steps.
|
|
9
|
+
|
|
10
|
+
## Quick start
|
|
11
|
+
|
|
12
|
+
From a project root containing `cuttlefish.config.ts`:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx @typecad/cuttlefish build
|
|
16
|
+
npx @typecad/cuttlefish build --compile --upload --port COM4
|
|
17
|
+
npx @typecad/cuttlefish build --compile --upload --monitor --port COM4 --baud 115200
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Scaffold a starter project with the built-in wizard:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx @typecad/cuttlefish create --board esp32s3
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Commands
|
|
27
|
+
|
|
28
|
+
| Command | Description |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| `cuttlefish build` | Transpile the entry file (default). Accepts `--compile`, `--upload`, `--monitor`, `--port`, `--baud`. |
|
|
31
|
+
| `cuttlefish create` | Generate a starter project and `cuttlefish.config.ts`. |
|
|
32
|
+
| `cuttlefish preview` | Launch the browser preview server for a UI project. |
|
|
33
|
+
| `cuttlefish gen-decls <file.h\|file.cpp\|--all <dir>>` | Generate `.d.ts` declaration stubs from C++ headers. |
|
|
34
|
+
| `cuttlefish doctor` | Check the active framework's environment (e.g. toolchain + board support). |
|
|
35
|
+
| `cuttlefish licenses [--all] [--strict]` | Scan this project's libraries for SPDX licenses. |
|
|
36
|
+
| `cuttlefish board sync [zephyr-base]` | Rebuild the local board catalog from your Zephyr tree's board DTS files. The catalog is machine-local — there is no compiled-in board database; builds create and refresh it automatically, this command forces a rebuild. |
|
|
37
|
+
| `cuttlefish board regen` | Regenerate the project-local board module (`.cuttlefish/board.ts` + `board.json`). Builds also regenerate it automatically whenever any input changes (config board, catalog, or Zephyr tree). |
|
|
38
|
+
| `cuttlefish library <search\|install\|init\|validate>` | The cuttlefish library package manager (npm keywords are the catalog). |
|
|
39
|
+
|
|
40
|
+
### Flags (for `build`)
|
|
41
|
+
|
|
42
|
+
- `--compile` — transpile, then compile via the active framework's toolchain (`west` for Zephyr, `g++` for native).
|
|
43
|
+
- `--upload` — flash firmware to the board (requires `--compile`).
|
|
44
|
+
- `--monitor` — open a serial monitor after upload.
|
|
45
|
+
- `--port <port>` — serial port for upload/monitor (e.g. `COM4`, `/dev/ttyUSB0`).
|
|
46
|
+
- `--baud <rate>` — serial monitor baud rate.
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
The CLI reads `cuttlefish.config.ts` from the current working directory and
|
|
51
|
+
treats it as the source of truth. When no config file is present, command-line
|
|
52
|
+
flags such as `--board` and `--build-target` supply board and build settings.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import type { CuttlefishConfig } from '@typecad/cuttlefish/api';
|
|
56
|
+
|
|
57
|
+
const config: CuttlefishConfig = {
|
|
58
|
+
entry: './src/main.ts',
|
|
59
|
+
board: 'xiao_ble/nrf52840',
|
|
60
|
+
framework: '@typecad/framework-zephyr',
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default config;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Ecosystem
|
|
67
|
+
|
|
68
|
+
`@typecad/cuttlefish` is the transpiler core. It pairs with sibling packages:
|
|
69
|
+
|
|
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-zephyr`](https://cuttlefish.typecad.net) — Zephyr RTOS framework (build, flashing, and the bundled Zephyr toolchain installer).
|
|
74
|
+
|
|
75
|
+
Built in, no separate package: the **native** desktop target (`framework:
|
|
76
|
+
'@typecad/framework-native'` resolves inside cuttlefish) and the **safety**
|
|
77
|
+
engine (verified GPIO reads, ISO 26262 analysis — author via
|
|
78
|
+
`@typecad/cuttlefish/safety`).
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# TypeCAD Debug
|
|
2
|
+
|
|
3
|
+
A Visual Studio Code extension that bridges VSCode's breakpoint gutter to the
|
|
4
|
+
TypeCAD `Serial.print` debug pipeline. Set breakpoints in your `.ts` source;
|
|
5
|
+
this extension syncs them to `.cuttlefish/breakpoints.json`, which the
|
|
6
|
+
`@typecad/cuttlefish` transpiler reads (when run with `--debug`) to inject
|
|
7
|
+
`Serial.println` instrumentation that reports variable values and lets you
|
|
8
|
+
step through execution.
|
|
9
|
+
|
|
10
|
+
This is the producer half of a two-part system. The consumer half lives in
|
|
11
|
+
[`@typecad/cuttlefish`](../../packages/cuttlefish/src/debug/) and is the
|
|
12
|
+
authoritative source for the on-disk schema and matching behavior described
|
|
13
|
+
below.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
This package is `private: true` and is **not** published to the npm registry
|
|
18
|
+
or the VS Code Marketplace. Build the VSIX locally:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
cd packages/vscode-typecad-debug
|
|
22
|
+
npm install
|
|
23
|
+
npm run compile
|
|
24
|
+
npm run package # produces vscode-typecad-debug-0.2.0.vsix
|
|
25
|
+
code --install-extension vscode-typecad-debug-0.2.0.vsix
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
1. Open the Command Palette (`Ctrl/Cmd+Shift+P`).
|
|
31
|
+
2. Run **TypeCAD: Debug with Breakpoints** — or set red-dot breakpoints in the
|
|
32
|
+
gutter and run `cuttlefish build --debug` in a terminal.
|
|
33
|
+
3. Breakpoints (including conditional breakpoints and logpoints) are written
|
|
34
|
+
to `.cuttlefish/breakpoints.json` on every breakpoint change and on every
|
|
35
|
+
`.ts` save.
|
|
36
|
+
4. Upload the instrumented firmware and open a serial monitor (`--monitor`).
|
|
37
|
+
At each breakpoint the firmware prints the location, the original source
|
|
38
|
+
line, and the variables in scope, then halts. Two keys are available:
|
|
39
|
+
- **ENTER** — continue (the breakpoint will halt here again the next time
|
|
40
|
+
execution reaches it).
|
|
41
|
+
- **`s`** — skip this breakpoint for the rest of the run: it won't halt
|
|
42
|
+
here again until the device reboots. Other breakpoints are unaffected.
|
|
43
|
+
|
|
44
|
+
### Commands
|
|
45
|
+
|
|
46
|
+
| Command | Title |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `typecad-debug.toggleBreakpoint` | TypeCAD: Toggle Breakpoint (bound to `F9` in `.ts` files) |
|
|
49
|
+
| `typecad-debug.clearAllBreakpoints` | TypeCAD: Clear All Breakpoints |
|
|
50
|
+
| `typecad-debug.debugWithBreakpoints` | TypeCAD: Debug with Breakpoints |
|
|
51
|
+
| `typecad-debug.syncBreakpoints` | TypeCAD: Sync Breakpoints from VS Code |
|
|
52
|
+
| `typecad-debug.generateDeclaration` | TypeCAD: Generate Declaration from C++ |
|
|
53
|
+
|
|
54
|
+
### Enabling instrumentation
|
|
55
|
+
|
|
56
|
+
Breakpoints are only injected when cuttlefish is run with `--debug`:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
cuttlefish build --debug # uses cuttlefish.config.ts entry
|
|
60
|
+
cuttlefish src/index.ts --debug --compile --upload --port COM4
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
See `cuttlefish --help` for the full `--debug` description.
|
|
64
|
+
|
|
65
|
+
## `.cuttlefish/breakpoints.json` schema
|
|
66
|
+
|
|
67
|
+
The file lives at the project root (or any ancestor of the entry file's
|
|
68
|
+
directory). Each entry uses **the basename** of the source file as `file`
|
|
69
|
+
(this is the only path form that matches reliably on both Windows and POSIX
|
|
70
|
+
under cuttlefish's basename-matching loader):
|
|
71
|
+
|
|
72
|
+
```jsonc
|
|
73
|
+
{
|
|
74
|
+
"breakpoints": [
|
|
75
|
+
{ "file": "index.ts", "line": 12 },
|
|
76
|
+
{ "file": "index.ts", "line": 27, "condition": "counter > 5" },
|
|
77
|
+
{ "file": "sensor.ts", "line": 8, "logMessage": "reading = {value}" }
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Field | Type | Required | Notes |
|
|
83
|
+
|---|---|---|---|
|
|
84
|
+
| `file` | string | yes | Source file **basename** (e.g. `index.ts`). |
|
|
85
|
+
| `line` | number | yes | 1-indexed line number. `0` is dropped. |
|
|
86
|
+
| `condition` | string | no | Conditional expression; `===`/`!==` are auto-normalized to `==`/`!=` for C++. |
|
|
87
|
+
| `logMessage` | string | no | Logpoint with `{variable}` interpolation. When present, the breakpoint logs instead of halting. |
|
|
88
|
+
|
|
89
|
+
Two source files sharing the same basename in one project will share
|
|
90
|
+
breakpoints — acceptable for typical single-program projects.
|
|
91
|
+
|
|
92
|
+
## Native debugging on ESP32-S3
|
|
93
|
+
|
|
94
|
+
For ESP32-S3, this extension's printf instrumentation is superseded by a
|
|
95
|
+
native GDB path. `cuttlefish build --debug` on `esp32s3` emits `#line`
|
|
96
|
+
directives in the generated C++ and writes `.vscode/launch.json` +
|
|
97
|
+
`tasks.json` (at the cuttlefish project root, where VS Code reads them) plus
|
|
98
|
+
`.cuttlefish/openocd.cfg` next to the build output. Press **F5** in VS Code
|
|
99
|
+
and the generated config attaches GDB to the chip's built-in USB-Serial-JTAG
|
|
100
|
+
— one USB cable, no external probe.
|
|
101
|
+
|
|
102
|
+
For Zephyr projects (`@typecad/framework-zephyr` on an esp32s3 board),
|
|
103
|
+
`cuttlefish create` writes the same starter artifacts at project creation —
|
|
104
|
+
`.vscode/launch.json` + `tasks.json` + `src/out/.cuttlefish/openocd.cfg` —
|
|
105
|
+
so F5 works on a fresh project before any build: the preLaunch task runs
|
|
106
|
+
`cuttlefish build --compile --upload --debug`, which builds, flashes, and
|
|
107
|
+
re-merges the launch entry with the build-cache-resolved gdbPath. (The
|
|
108
|
+
starter gdbPath is probed from `$ZEPHYR_SDK_INSTALL_DIR`, the
|
|
109
|
+
zephyr-installer micromamba layout, or `~/zephyr-sdk-*`.)
|
|
110
|
+
|
|
111
|
+
`launch.json` ships a single **`cortex-debug`** configuration (`servertype:
|
|
112
|
+
"openocd"`, or `"jlink"` when the board's probe method is a JLink runner).
|
|
113
|
+
The cortex-debug extension starts OpenOCD itself as a child process, passing
|
|
114
|
+
the generated `.cuttlefish/openocd.cfg`; the `preLaunchTask` is just
|
|
115
|
+
`build + flash` — no competing OpenOCD process. Install the cortex-debug
|
|
116
|
+
extension (ESP32 targets also need OpenOCD — the framework probes the
|
|
117
|
+
openocd-esp32 install layout or the Zephyr SDK's own openocd), and set the
|
|
118
|
+
serial port through the `CUTTLEFISH_PORT` env var or pass
|
|
119
|
+
`--port`.
|
|
120
|
+
|
|
121
|
+
The printf instrumentation documented below remains the path for targets
|
|
122
|
+
that don't ship a native GDB path yet.
|
|
123
|
+
|
|
124
|
+
## Limitations
|
|
125
|
+
|
|
126
|
+
- This is a printf-based instrumentation shim, not a DAP debug
|
|
127
|
+
adapter. There is no native step/step-in/step-out — each breakpoint halts
|
|
128
|
+
until ENTER (continue) or `s` (skip this breakpoint for the run) is received
|
|
129
|
+
over serial. **On ESP32-S3, use the native GDB path above instead** — it
|
|
130
|
+
provides full stepping, call stacks, and TS-named variable inspection.
|
|
131
|
+
- The scope analyzer captures module-scope identifiers plus locals and
|
|
132
|
+
parameters in the enclosing function. Member access and arbitrary
|
|
133
|
+
expressions are not resolved; `{ value }` in a logpoint emits the literal
|
|
134
|
+
`"{value}"` if `value` is not in scope.
|
|
135
|
+
- Baud rate is fixed by the framework's console shim regardless of the CLI
|
|
136
|
+
`--baud` value.
|
|
137
|
+
- **Target-specific output:** under @typecad/framework-zephyr the injected
|
|
138
|
+
code routes through the board console (`printk`/shell backend) and blocks on
|
|
139
|
+
a getchar-equivalent with the idle thread feeding — so a debug build must
|
|
140
|
+
have a serial monitor attached (e.g. `cuttlefish build --monitor`), or it
|
|
141
|
+
will hang at the first breakpoint until power is cycled.
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// vscode-typecad-debug — VSCode Extension
|
|
4
|
+
//
|
|
5
|
+
// Tracks breakpoints in TypeScript files and syncs them to
|
|
6
|
+
// .cuttlefish/breakpoints.json for the TypeCAD debug preprocessor.
|
|
7
|
+
// Also auto-generates .d.ts declaration files from C++ sources.
|
|
8
|
+
//
|
|
9
|
+
// The breakpoint file is read by @typecad/cuttlefish when invoked with
|
|
10
|
+
// `--debug`. The preprocessor injects Serial.println instrumentation at the
|
|
11
|
+
// recorded line numbers; run `cuttlefish build --debug` (or `cuttlefish
|
|
12
|
+
// index.ts --debug`) to enable it.
|
|
13
|
+
//
|
|
14
|
+
// IMPORTANT: the `file` field in each breakpoint entry is written as the
|
|
15
|
+
// basename only (e.g. "index.ts"). The cuttlefish loader matches breakpoints
|
|
16
|
+
// by exact → basename → suffix, and basename matching is the only strategy
|
|
17
|
+
// that works identically on Windows (backslash) and POSIX (forward slash)
|
|
18
|
+
// without slash normalization. The trade-off is that two files with the same
|
|
19
|
+
// basename in one project share breakpoints — acceptable for typical
|
|
20
|
+
// single-sketch Arduino projects.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
39
|
+
var ownKeys = function(o) {
|
|
40
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
41
|
+
var ar = [];
|
|
42
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
43
|
+
return ar;
|
|
44
|
+
};
|
|
45
|
+
return ownKeys(o);
|
|
46
|
+
};
|
|
47
|
+
return function (mod) {
|
|
48
|
+
if (mod && mod.__esModule) return mod;
|
|
49
|
+
var result = {};
|
|
50
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
51
|
+
__setModuleDefault(result, mod);
|
|
52
|
+
return result;
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
55
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
+
exports.activate = activate;
|
|
57
|
+
exports.deactivate = deactivate;
|
|
58
|
+
const vscode = __importStar(require("vscode"));
|
|
59
|
+
const fs = __importStar(require("node:fs"));
|
|
60
|
+
const path = __importStar(require("node:path"));
|
|
61
|
+
const node_child_process_1 = require("node:child_process");
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Constants
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/** Relative to the workspace root. */
|
|
66
|
+
const BREAKPOINTS_DIR = '.cuttlefish';
|
|
67
|
+
const BREAKPOINTS_FILE = 'breakpoints.json';
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Extension Activation
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
function activate(context) {
|
|
72
|
+
console.log('TypeCAD Debug extension activated');
|
|
73
|
+
const breakpointTracker = new BreakpointTracker();
|
|
74
|
+
const toggleCmd = vscode.commands.registerCommand('typecad-debug.toggleBreakpoint', () => breakpointTracker.toggleBreakpoint());
|
|
75
|
+
const clearAllCmd = vscode.commands.registerCommand('typecad-debug.clearAllBreakpoints', () => breakpointTracker.clearAllBreakpoints());
|
|
76
|
+
const debugCmd = vscode.commands.registerCommand('typecad-debug.debugWithBreakpoints', () => breakpointTracker.debugWithBreakpoints());
|
|
77
|
+
const syncCmd = vscode.commands.registerCommand('typecad-debug.syncBreakpoints', () => breakpointTracker.syncFromVSCode());
|
|
78
|
+
// Auto-sync breakpoints when saving TypeScript files.
|
|
79
|
+
const saveListener = vscode.workspace.onDidSaveTextDocument((doc) => {
|
|
80
|
+
if (doc.fileName.endsWith('.ts') && !doc.fileName.includes('node_modules')) {
|
|
81
|
+
breakpointTracker.syncFromVSCode();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
const declGenerator = new DeclarationGenerator();
|
|
85
|
+
const genDeclCmd = vscode.commands.registerCommand('typecad-debug.generateDeclaration', () => declGenerator.generateForCurrentFile());
|
|
86
|
+
// Auto-generate a .d.ts when a C++ file is saved and the sidecar is missing.
|
|
87
|
+
const cppSaveListener = vscode.workspace.onDidSaveTextDocument((doc) => {
|
|
88
|
+
if (doc.fileName.endsWith('.cpp') && !doc.fileName.includes('node_modules')) {
|
|
89
|
+
declGenerator.checkAndGenerate(doc.fileName);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
context.subscriptions.push(toggleCmd, clearAllCmd, debugCmd, syncCmd, saveListener, breakpointTracker, genDeclCmd, cppSaveListener, declGenerator);
|
|
93
|
+
}
|
|
94
|
+
function deactivate() { }
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
// Breakpoint Tracker
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
class BreakpointTracker {
|
|
99
|
+
constructor() {
|
|
100
|
+
/** file fsPath → line → Breakpoint. Keys are full fsPaths for dedup. */
|
|
101
|
+
this.breakpoints = new Map();
|
|
102
|
+
this._onDidChange = new vscode.EventEmitter();
|
|
103
|
+
this.onDidChange = this._onDidChange.event;
|
|
104
|
+
this.loadFromFile();
|
|
105
|
+
// VSCode breakpoint gutter changes (red dots, conditions, logpoints).
|
|
106
|
+
vscode.debug.onDidChangeBreakpoints(() => {
|
|
107
|
+
console.log('TypeCAD: Breakpoint change detected');
|
|
108
|
+
this.syncFromVSCode();
|
|
109
|
+
});
|
|
110
|
+
// Re-sync when switching editor so a stale in-memory map doesn't survive.
|
|
111
|
+
vscode.window.onDidChangeActiveTextEditor((editor) => {
|
|
112
|
+
if (editor) {
|
|
113
|
+
this.syncFromVSCode();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Toggle a breakpoint at the current cursor position.
|
|
119
|
+
*/
|
|
120
|
+
toggleBreakpoint() {
|
|
121
|
+
const editor = vscode.window.activeTextEditor;
|
|
122
|
+
if (!editor)
|
|
123
|
+
return;
|
|
124
|
+
const filePath = editor.document.uri.fsPath;
|
|
125
|
+
const fileName = path.basename(filePath);
|
|
126
|
+
const line = editor.selection.active.line + 1; // 1-indexed
|
|
127
|
+
if (!this.breakpoints.has(fileName)) {
|
|
128
|
+
this.breakpoints.set(fileName, new Map());
|
|
129
|
+
}
|
|
130
|
+
const fileBreakpoints = this.breakpoints.get(fileName);
|
|
131
|
+
if (fileBreakpoints.has(line)) {
|
|
132
|
+
fileBreakpoints.delete(line);
|
|
133
|
+
vscode.window.showInformationMessage(`TypeCAD: Breakpoint removed at line ${line}`);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
fileBreakpoints.set(line, { file: fileName, line });
|
|
137
|
+
vscode.window.showInformationMessage(`TypeCAD: Breakpoint added at line ${line}`);
|
|
138
|
+
}
|
|
139
|
+
this.saveToFile();
|
|
140
|
+
this._onDidChange.fire();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Clear all breakpoints.
|
|
144
|
+
*/
|
|
145
|
+
clearAllBreakpoints() {
|
|
146
|
+
this.breakpoints.clear();
|
|
147
|
+
this.saveToFile();
|
|
148
|
+
vscode.window.showInformationMessage('TypeCAD: All breakpoints cleared');
|
|
149
|
+
this._onDidChange.fire();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Save breakpoints, then run `cuttlefish build --debug` in a terminal.
|
|
153
|
+
*/
|
|
154
|
+
async debugWithBreakpoints() {
|
|
155
|
+
const editor = vscode.window.activeTextEditor;
|
|
156
|
+
if (!editor) {
|
|
157
|
+
vscode.window.showErrorMessage('TypeCAD: No active editor');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.saveToFile();
|
|
161
|
+
const terminal = vscode.window.createTerminal('TypeCAD Debug');
|
|
162
|
+
terminal.show();
|
|
163
|
+
terminal.sendText('npx cuttlefish build --debug');
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Sync breakpoints from VSCode's built-in breakpoint system.
|
|
167
|
+
* Captures conditional breakpoints and logpoints.
|
|
168
|
+
* REPLACES all breakpoints with the current VS Code state.
|
|
169
|
+
*/
|
|
170
|
+
syncFromVSCode() {
|
|
171
|
+
const vscodeBreakpoints = vscode.debug.breakpoints;
|
|
172
|
+
console.log(`TypeCAD: Syncing ${vscodeBreakpoints.length} breakpoints from VS Code`);
|
|
173
|
+
this.breakpoints.clear();
|
|
174
|
+
let count = 0;
|
|
175
|
+
for (const bp of vscodeBreakpoints) {
|
|
176
|
+
if (bp instanceof vscode.SourceBreakpoint) {
|
|
177
|
+
// Key the in-memory map by basename so saveToFile and the toggle path
|
|
178
|
+
// agree on a single canonical key. The loader matches by basename.
|
|
179
|
+
const filePath = bp.location.uri.fsPath;
|
|
180
|
+
const fileName = path.basename(filePath);
|
|
181
|
+
const line = bp.location.range.start.line + 1; // 1-indexed
|
|
182
|
+
if (!this.breakpoints.has(fileName)) {
|
|
183
|
+
this.breakpoints.set(fileName, new Map());
|
|
184
|
+
}
|
|
185
|
+
this.breakpoints.get(fileName).set(line, {
|
|
186
|
+
file: fileName,
|
|
187
|
+
line,
|
|
188
|
+
condition: bp.condition,
|
|
189
|
+
logMessage: bp.logMessage, // LogMessageBreakpoint has this property
|
|
190
|
+
});
|
|
191
|
+
count++;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
this.saveToFile();
|
|
195
|
+
vscode.window.setStatusBarMessage(`TypeCAD: Synced ${count} breakpoints`, 3000);
|
|
196
|
+
console.log(`TypeCAD: Synced ${count} breakpoints to file`);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Load breakpoints from .cuttlefish/breakpoints.json
|
|
200
|
+
*/
|
|
201
|
+
loadFromFile() {
|
|
202
|
+
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
203
|
+
if (!workspaceFolders || workspaceFolders.length === 0)
|
|
204
|
+
return;
|
|
205
|
+
const filePath = path.join(workspaceFolders[0].uri.fsPath, BREAKPOINTS_DIR, BREAKPOINTS_FILE);
|
|
206
|
+
if (!fs.existsSync(filePath))
|
|
207
|
+
return;
|
|
208
|
+
try {
|
|
209
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
210
|
+
const map = JSON.parse(content);
|
|
211
|
+
for (const bp of map.breakpoints ?? []) {
|
|
212
|
+
if (!this.breakpoints.has(bp.file)) {
|
|
213
|
+
this.breakpoints.set(bp.file, new Map());
|
|
214
|
+
}
|
|
215
|
+
this.breakpoints.get(bp.file).set(bp.line, bp);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.error('TypeCAD: Failed to load breakpoints:', err);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Save breakpoints to .cuttlefish/breakpoints.json atomically.
|
|
224
|
+
* Writes to a temp file then renames, so a watching transpiler never reads
|
|
225
|
+
* a half-written file.
|
|
226
|
+
*/
|
|
227
|
+
saveToFile() {
|
|
228
|
+
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
229
|
+
if (!workspaceFolders || workspaceFolders.length === 0) {
|
|
230
|
+
console.log('TypeCAD: No workspace folder, skipping save');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const dirPath = path.join(workspaceFolders[0].uri.fsPath, BREAKPOINTS_DIR);
|
|
234
|
+
const filePath = path.join(dirPath, BREAKPOINTS_FILE);
|
|
235
|
+
const tmpPath = `${filePath}.tmp`;
|
|
236
|
+
try {
|
|
237
|
+
if (!fs.existsSync(dirPath)) {
|
|
238
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (mkdirErr) {
|
|
242
|
+
console.error('TypeCAD: Failed to create directory:', mkdirErr);
|
|
243
|
+
vscode.window.showErrorMessage(`TypeCAD: Failed to create ${BREAKPOINTS_DIR} directory: ${mkdirErr}`);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const map = { breakpoints: [] };
|
|
247
|
+
for (const [, fileBreakpoints] of this.breakpoints) {
|
|
248
|
+
for (const [, bp] of fileBreakpoints) {
|
|
249
|
+
map.breakpoints.push(bp);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// Stable order for clean diffs and reproducible output.
|
|
253
|
+
map.breakpoints.sort((a, b) => {
|
|
254
|
+
if (a.file !== b.file)
|
|
255
|
+
return a.file.localeCompare(b.file);
|
|
256
|
+
return a.line - b.line;
|
|
257
|
+
});
|
|
258
|
+
try {
|
|
259
|
+
fs.writeFileSync(tmpPath, JSON.stringify(map, null, 2));
|
|
260
|
+
fs.renameSync(tmpPath, filePath);
|
|
261
|
+
console.log(`TypeCAD: Saved ${map.breakpoints.length} breakpoints to ${filePath}`);
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
// Best effort: clean up the temp file on failure.
|
|
265
|
+
try {
|
|
266
|
+
fs.unlinkSync(tmpPath);
|
|
267
|
+
}
|
|
268
|
+
catch { }
|
|
269
|
+
console.error('TypeCAD: Failed to save breakpoints:', err);
|
|
270
|
+
vscode.window.showErrorMessage(`TypeCAD: Failed to save breakpoints: ${err}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
dispose() {
|
|
274
|
+
this._onDidChange.dispose();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
// Declaration Generator
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
class DeclarationGenerator {
|
|
281
|
+
/**
|
|
282
|
+
* Generate a .d.ts sidecar for a C++ file if one is not already present.
|
|
283
|
+
*/
|
|
284
|
+
async checkAndGenerate(cppPath) {
|
|
285
|
+
const declPath = cppPath.replace(/\.cpp$/i, '.d.ts');
|
|
286
|
+
if (fs.existsSync(declPath)) {
|
|
287
|
+
return; // Already exists — never clobber.
|
|
288
|
+
}
|
|
289
|
+
const result = await this.generateDeclaration(cppPath, declPath);
|
|
290
|
+
if (result) {
|
|
291
|
+
vscode.window.showInformationMessage(`TypeCAD: Generated ${path.basename(declPath)} from ${path.basename(cppPath)}. Review and adjust types if needed.`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Generate a declaration for the currently active C++ file.
|
|
296
|
+
*/
|
|
297
|
+
async generateForCurrentFile() {
|
|
298
|
+
const editor = vscode.window.activeTextEditor;
|
|
299
|
+
if (!editor) {
|
|
300
|
+
vscode.window.showErrorMessage('TypeCAD: No active editor');
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const filePath = editor.document.uri.fsPath;
|
|
304
|
+
if (!filePath.endsWith('.cpp')) {
|
|
305
|
+
vscode.window.showErrorMessage('TypeCAD: Active file must be a .cpp file');
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const declPath = filePath.replace(/\.cpp$/i, '.d.ts');
|
|
309
|
+
const result = await this.generateDeclaration(filePath, declPath);
|
|
310
|
+
if (result) {
|
|
311
|
+
vscode.window.showInformationMessage(`TypeCAD: Generated ${path.basename(declPath)}`);
|
|
312
|
+
const doc = await vscode.workspace.openTextDocument(result);
|
|
313
|
+
await vscode.window.showTextDocument(doc);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
vscode.window.showWarningMessage('TypeCAD: No classes or constants found in C++ file');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Generate a .d.ts file from a C++ file via the cuttlefish CLI.
|
|
321
|
+
* Uses the monorepo source directly when developing inside this repo,
|
|
322
|
+
* falls back to `npx cuttlefish` for installed users.
|
|
323
|
+
*/
|
|
324
|
+
async generateDeclaration(cppPath, declPath) {
|
|
325
|
+
return new Promise((resolve) => {
|
|
326
|
+
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
327
|
+
// Local-CLI fallback for development inside the typecode monorepo.
|
|
328
|
+
const localCliPath = workspaceFolders
|
|
329
|
+
? path.join(workspaceFolders[0].uri.fsPath, 'packages/cuttlefish/src/cli.ts')
|
|
330
|
+
: null;
|
|
331
|
+
const cmd = localCliPath && fs.existsSync(localCliPath)
|
|
332
|
+
? `npx tsx "${localCliPath}" gen-decls "${cppPath}"`
|
|
333
|
+
: `npx cuttlefish gen-decls "${cppPath}"`;
|
|
334
|
+
(0, node_child_process_1.exec)(cmd, { cwd: workspaceFolders?.[0]?.uri.fsPath }, (error) => {
|
|
335
|
+
if (error) {
|
|
336
|
+
console.error('TypeCAD: Failed to generate declaration:', error);
|
|
337
|
+
vscode.window.showErrorMessage(`TypeCAD: Failed to generate declaration: ${error.message}`);
|
|
338
|
+
resolve(null);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
resolve(fs.existsSync(declPath) ? declPath : null);
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
dispose() { }
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=extension.js.map
|