@typecad/cuttlefish 1.0.0-alpha.12 → 1.0.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/editor-extensions/typecad-debug/README.md +142 -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/add-preset.d.ts +4 -0
- package/dist/add-preset.js +74 -0
- package/dist/api/config.d.ts +8 -5
- package/dist/api/shared/display-adapters/sdl.js +1 -1
- package/dist/api/shared/display-profile.d.ts +11 -0
- package/dist/api/shared/display-profile.js +3 -0
- package/dist/api/shared/framework-manifest.d.ts +61 -504
- package/dist/api/shared/hal-op-ir.d.ts +19 -0
- package/dist/api/shared/toolchain-types.d.ts +0 -1
- package/dist/cli.js +31 -9
- package/dist/config-loader.d.ts +0 -2
- package/dist/config-loader.js +13 -6
- package/dist/config-schema.d.ts +17 -230
- package/dist/config-schema.js +1 -3
- package/dist/contract/contract-parser.d.ts +9 -127
- package/dist/create/board-checklist.js +1 -1
- package/dist/create/board-codegen.js +4 -4
- package/dist/create/board-spec.d.ts +74 -530
- package/dist/create/debug-artifacts.d.ts +20 -0
- package/dist/create/debug-artifacts.js +69 -0
- package/dist/create/editor-integration.d.ts +30 -0
- package/dist/create/editor-integration.js +218 -0
- package/dist/create/eslint-rules-template.d.ts +2 -2
- package/dist/create/framework-catalog.d.ts +8 -0
- package/dist/create/framework-catalog.js +28 -5
- package/dist/create/index.d.ts +9 -6
- package/dist/create/index.js +6 -4
- package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +5 -4
- package/dist/create/{init-scaffold.js → scaffold.js} +38 -2
- package/dist/create/templates.d.ts +29 -0
- package/dist/create/{init-templates.js → templates.js} +15 -2
- package/dist/create/wizard.d.ts +8 -0
- package/dist/create/{init-wizard.js → wizard.js} +11 -4
- package/dist/emit/compliance/rules.js +18 -4
- package/dist/emit/emitters/function-emitter-impl.js +7 -1
- package/dist/emit/emitters/line-appender.js +6 -0
- package/dist/emit/emitters/setup.js +22 -0
- package/dist/emit/emitters/ui-emitter.js +40 -15
- package/dist/emit/route-hal-op.js +55 -1
- package/dist/emit/statement-renderer.js +5 -2
- package/dist/ir/build-ir.js +46 -4
- package/dist/ir/expression-to-ir.js +17 -0
- package/dist/ir/hal/hal-emitter.js +23 -5
- package/dist/ir/hal/hal-plugins.js +11 -0
- package/dist/ir/pin-mode-validation.js +32 -9
- package/dist/ir/pin-state-tracking.d.ts +58 -0
- package/dist/ir/pin-state-tracking.js +182 -0
- package/dist/ir/program-analysis.d.ts +6 -0
- package/dist/ir/program-analysis.js +38 -0
- package/dist/ir/statement-to-ir.js +14 -0
- package/dist/ir/transformers/control-flow.js +29 -0
- package/dist/ir/transformers/ui-call-resolver.js +105 -1
- package/dist/ir/ui-element-auto-wire.js +7 -4
- 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/orchestrator/graph-builder.d.ts +4 -1
- package/dist/orchestrator/graph-builder.js +23 -1
- package/dist/preview/api-shared-shim.d.ts +1 -0
- package/dist/preview/api-shared-shim.js +7 -0
- package/dist/preview/client.js +235 -2
- package/dist/preview/server.js +154 -62
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +1 -1
- package/dist/theme-tokens.d.ts +22 -0
- package/dist/theme-tokens.js +172 -0
- package/dist/transpile.js +90 -5
- package/dist/types.d.ts +24 -0
- package/dist/ui-hook.d.ts +7 -0
- package/dist/utils/cli.d.ts +2 -2
- package/dist/utils/cli.js +77 -3
- package/dist/utils/ui.d.ts +5 -0
- package/dist/utils/ui.js +7 -0
- package/package.json +18 -9
- package/dist/create/init-templates.d.ts +0 -28
- package/dist/create/init-wizard.d.ts +0 -8
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface FrameworkDebugArtifactsOptions {
|
|
2
|
+
/** Framework package name (e.g. '@typecad/framework-zephyr'), if known. */
|
|
3
|
+
frameworkPackage?: string;
|
|
4
|
+
/** Absolute path to the new cuttlefish project root. */
|
|
5
|
+
workspaceRoot: string;
|
|
6
|
+
/** The framework build target (e.g. Zephyr board id), if known. */
|
|
7
|
+
buildTarget?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Module loader for the framework package. Returns the loaded module, or
|
|
11
|
+
* undefined when it cannot be resolved. Injectable for tests.
|
|
12
|
+
*/
|
|
13
|
+
export type FrameworkModuleLoader = (packageName: string) => any | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Generate the framework's starter debug artifacts for a new project.
|
|
16
|
+
* Returns the workspace-relative paths written (e.g. ['.vscode/launch.json']),
|
|
17
|
+
* or [] when the framework has no debug support, isn't resolvable yet, or the
|
|
18
|
+
* generator failed (warns, never throws).
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateFrameworkDebugArtifacts(o: FrameworkDebugArtifactsOptions, loadModule?: FrameworkModuleLoader): string[];
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// debug-artifacts.ts — create-time framework debug profile generation
|
|
3
|
+
//
|
|
4
|
+
// `cuttlefish create` scaffolds a project that has never been built, so the
|
|
5
|
+
// framework toolchain's post-build debug-artifact writer (e.g. Zephyr's
|
|
6
|
+
// writeDebugConfig, which runs after a successful `west build --debug`) has
|
|
7
|
+
// never had a chance to run. Without a .vscode/launch.json, pressing F5 in VS
|
|
8
|
+
// Code just opens the "select a debugger" menu.
|
|
9
|
+
//
|
|
10
|
+
// Frameworks that support native debugging may export
|
|
11
|
+
// `writeProjectDebugArtifacts({ workspaceRoot, buildTarget })` from their
|
|
12
|
+
// package root (see @typecad/framework-zephyr). This helper loads the freshly
|
|
13
|
+
// installed framework package and invokes that export — the framework decides
|
|
14
|
+
// whether the target is debug-capable and what to write. Frameworks without
|
|
15
|
+
// the export (or targets without native debug support) are a silent no-op.
|
|
16
|
+
//
|
|
17
|
+
// Everything here is best-effort: a failed or skipped generation never fails
|
|
18
|
+
// `cuttlefish create`, because the first `--debug` build still writes the
|
|
19
|
+
// artifacts the hard way.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { loadFrameworkPackage } from "../framework-package.js";
|
|
24
|
+
const cliModuleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
/**
|
|
26
|
+
* Generate the framework's starter debug artifacts for a new project.
|
|
27
|
+
* Returns the workspace-relative paths written (e.g. ['.vscode/launch.json']),
|
|
28
|
+
* or [] when the framework has no debug support, isn't resolvable yet, or the
|
|
29
|
+
* generator failed (warns, never throws).
|
|
30
|
+
*/
|
|
31
|
+
export function generateFrameworkDebugArtifacts(o, loadModule) {
|
|
32
|
+
if (!o.frameworkPackage || !o.workspaceRoot)
|
|
33
|
+
return [];
|
|
34
|
+
// Default loader: prefer the new project's node_modules (populated by the
|
|
35
|
+
// create install step), then the CLI's own module location (monorepo /
|
|
36
|
+
// --no-install flows where the framework is a workspace sibling of the
|
|
37
|
+
// running cuttlefish).
|
|
38
|
+
const loader = loadModule ?? ((packageName) => {
|
|
39
|
+
for (const dir of [o.workspaceRoot, cliModuleDir]) {
|
|
40
|
+
try {
|
|
41
|
+
return loadFrameworkPackage(packageName, dir);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// not resolvable from this location — try the next
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
});
|
|
49
|
+
let mod;
|
|
50
|
+
try {
|
|
51
|
+
mod = loader(o.frameworkPackage);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
if (!mod || typeof mod.writeProjectDebugArtifacts !== "function")
|
|
57
|
+
return [];
|
|
58
|
+
try {
|
|
59
|
+
const written = mod.writeProjectDebugArtifacts({
|
|
60
|
+
workspaceRoot: o.workspaceRoot,
|
|
61
|
+
buildTarget: o.buildTarget,
|
|
62
|
+
});
|
|
63
|
+
return Array.isArray(written) ? written.map(String) : [];
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
console.warn(`! Debug profile generation failed: ${e.message}`);
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** VS Code extension identifiers (publisher.name) of the bundled extensions. */
|
|
2
|
+
export declare const TYPECAD_UI_EXTENSION_ID = "typecad.typecad-ui";
|
|
3
|
+
export declare const TYPECAD_DEBUG_EXTENSION_ID = "typecad.vscode-typecad-debug";
|
|
4
|
+
/**
|
|
5
|
+
* Source location of an unpacked bundled extension inside the cuttlefish
|
|
6
|
+
* package. Resolved from this module's location so it works from both src/
|
|
7
|
+
* (dev and tests importing source) and dist/ (the published CLI) — assets/
|
|
8
|
+
* sits at the package root either way.
|
|
9
|
+
*/
|
|
10
|
+
export declare function bundledExtensionSourceDir(dir: string): string;
|
|
11
|
+
/** Kept for compatibility with the original single-extension helper. */
|
|
12
|
+
export declare function typecadUiExtensionSourceDir(): string;
|
|
13
|
+
/** Content of .vscode/extensions.json — auto-installs the workspace-bundled extensions. */
|
|
14
|
+
export declare function generateExtensionsJson(): string;
|
|
15
|
+
export declare const WATCH_TASK_LABEL = "cuttlefish: watch build";
|
|
16
|
+
/** The watch task entry written to .vscode/tasks.json. */
|
|
17
|
+
export declare function watchBuildTask(): Record<string, unknown>;
|
|
18
|
+
/**
|
|
19
|
+
* Content of .vscode/tasks.json containing the watch task. Kept separate from
|
|
20
|
+
* the merge logic so tests can assert the shape without a filesystem.
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateTasksJson(existingTasks?: ReadonlyArray<Record<string, unknown>>): string;
|
|
23
|
+
/**
|
|
24
|
+
* Copy the bundled extensions into <outDir>/.vscode/extensions/, then write the
|
|
25
|
+
* companion .vscode/extensions.json and — when the project has a `dev` watch
|
|
26
|
+
* script — the .vscode/tasks.json watch task. Returns the absolute paths
|
|
27
|
+
* written, or [] when the extension assets are missing (warns, never throws).
|
|
28
|
+
* `assetsRoot` overrides the bundled-asset location (tests).
|
|
29
|
+
*/
|
|
30
|
+
export declare function writeEditorIntegration(outDir: string, assetsRoot?: string): string[];
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// editor-integration.ts — create-time editor scaffolding for .ui highlighting
|
|
3
|
+
//
|
|
4
|
+
// Cuttlefish projects keep their UI in .ui single-file components (TS script +
|
|
5
|
+
// CSS style + Svelte-style markup), which no editor knows out of the box. The
|
|
6
|
+
// package ships grammar-only VS Code extensions under
|
|
7
|
+
// assets/editor-extensions/ and `cuttlefish create` copies them into the new
|
|
8
|
+
// project's .vscode/extensions/ folder:
|
|
9
|
+
//
|
|
10
|
+
// typecad-ui — .ui syntax highlighting, snippets, file icons, markdown
|
|
11
|
+
// ```ui fence highlighting (grammar-only, no code).
|
|
12
|
+
// typecad-debug — the built TypeCAD Debug extension (breakpoint syncing +
|
|
13
|
+
// F5 commands), so debugging works with zero install.
|
|
14
|
+
//
|
|
15
|
+
// VS Code (1.89+, trusted workspaces) detects workspace-bundled extensions and
|
|
16
|
+
// installs them scoped to that workspace. The companion .vscode/extensions.json
|
|
17
|
+
// carries forceInstall entries (microsoft/vscode#299830) so VS Code builds with
|
|
18
|
+
// that feature skip the approval prompt; older builds show a one-time install
|
|
19
|
+
// prompt instead.
|
|
20
|
+
//
|
|
21
|
+
// A .vscode/tasks.json watch task is also written: it runs the project's
|
|
22
|
+
// `cuttlefish build --watch` dev script with NO_COLOR=1 and parses the
|
|
23
|
+
// transpiler/ESLint diagnostic lines into Problems-panel squiggles. The task
|
|
24
|
+
// merges by label (never clobbers user edits or the framework debug writer's
|
|
25
|
+
// tasks, which merge the same way).
|
|
26
|
+
//
|
|
27
|
+
// Everything here is best-effort like the debug-artifact generation: a missing
|
|
28
|
+
// or unreadable asset tree warns and skips rather than failing `cuttlefish
|
|
29
|
+
// create`, because a project without editor integration still builds fine.
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
import fs from 'node:fs';
|
|
32
|
+
import path from 'node:path';
|
|
33
|
+
import { fileURLToPath } from 'node:url';
|
|
34
|
+
/** VS Code extension identifiers (publisher.name) of the bundled extensions. */
|
|
35
|
+
export const TYPECAD_UI_EXTENSION_ID = 'typecad.typecad-ui';
|
|
36
|
+
export const TYPECAD_DEBUG_EXTENSION_ID = 'typecad.vscode-typecad-debug';
|
|
37
|
+
/** Extensions to bundle, as { asset folder name → extension id } pairs. */
|
|
38
|
+
const BUNDLED_EXTENSIONS = [
|
|
39
|
+
{ dir: 'typecad-ui', id: TYPECAD_UI_EXTENSION_ID },
|
|
40
|
+
{ dir: 'typecad-debug', id: TYPECAD_DEBUG_EXTENSION_ID },
|
|
41
|
+
];
|
|
42
|
+
const ASSETS_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'assets', 'editor-extensions');
|
|
43
|
+
/**
|
|
44
|
+
* Source location of an unpacked bundled extension inside the cuttlefish
|
|
45
|
+
* package. Resolved from this module's location so it works from both src/
|
|
46
|
+
* (dev and tests importing source) and dist/ (the published CLI) — assets/
|
|
47
|
+
* sits at the package root either way.
|
|
48
|
+
*/
|
|
49
|
+
export function bundledExtensionSourceDir(dir) {
|
|
50
|
+
return path.join(ASSETS_ROOT, dir);
|
|
51
|
+
}
|
|
52
|
+
/** Kept for compatibility with the original single-extension helper. */
|
|
53
|
+
export function typecadUiExtensionSourceDir() {
|
|
54
|
+
return bundledExtensionSourceDir('typecad-ui');
|
|
55
|
+
}
|
|
56
|
+
/** Content of .vscode/extensions.json — auto-installs the workspace-bundled extensions. */
|
|
57
|
+
export function generateExtensionsJson() {
|
|
58
|
+
return `${JSON.stringify({ forceInstall: BUNDLED_EXTENSIONS.map(e => e.id) }, null, 2)}\n`;
|
|
59
|
+
}
|
|
60
|
+
// -- watch task + problem matchers ------------------------------------------------
|
|
61
|
+
/**
|
|
62
|
+
* Problem matchers for cuttlefish's two diagnostic line formats:
|
|
63
|
+
* transpiler: "<file> error|warning [code] (line,column): message"
|
|
64
|
+
* eslint gate: "error <file>(line,column) [rule]: message"
|
|
65
|
+
* NO_COLOR=1 is set on the task so chalk stays off and the lines stay greppable.
|
|
66
|
+
*/
|
|
67
|
+
const PROBLEM_MATCHERS = [
|
|
68
|
+
{
|
|
69
|
+
owner: 'cuttlefish-transpiler',
|
|
70
|
+
severity: 'error',
|
|
71
|
+
fileLocation: ['relative', '${workspaceFolder}'],
|
|
72
|
+
pattern: {
|
|
73
|
+
regexp: '^\\s*(.*?)\\s+(error|warning)(?:\\s+\\[[^\\]]*\\])?\\s*\\((\\d+),(\\d+)\\):\\s+(.*)$',
|
|
74
|
+
file: 1,
|
|
75
|
+
severity: 2,
|
|
76
|
+
line: 3,
|
|
77
|
+
column: 4,
|
|
78
|
+
message: 5,
|
|
79
|
+
},
|
|
80
|
+
background: {
|
|
81
|
+
beginsPattern: 'Transpiling',
|
|
82
|
+
endsPattern: 'Watching for changes',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
owner: 'cuttlefish-eslint',
|
|
87
|
+
severity: 'error',
|
|
88
|
+
fileLocation: ['relative', '${workspaceFolder}'],
|
|
89
|
+
pattern: {
|
|
90
|
+
regexp: '^\\s*error\\s+(.*?)\\((\\d+),(\\d+)\\)\\s+\\[[^\\]]*\\]:\\s+(.*)$',
|
|
91
|
+
file: 1,
|
|
92
|
+
line: 2,
|
|
93
|
+
column: 3,
|
|
94
|
+
message: 4,
|
|
95
|
+
},
|
|
96
|
+
background: {
|
|
97
|
+
beginsPattern: 'Transpiling',
|
|
98
|
+
endsPattern: 'Watching for changes',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
export const WATCH_TASK_LABEL = 'cuttlefish: watch build';
|
|
103
|
+
/** The watch task entry written to .vscode/tasks.json. */
|
|
104
|
+
export function watchBuildTask() {
|
|
105
|
+
return {
|
|
106
|
+
label: WATCH_TASK_LABEL,
|
|
107
|
+
command: 'npm run dev',
|
|
108
|
+
type: 'shell',
|
|
109
|
+
isBackground: true,
|
|
110
|
+
group: 'build',
|
|
111
|
+
options: { env: { NO_COLOR: '1' } },
|
|
112
|
+
problemMatcher: PROBLEM_MATCHERS,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Content of .vscode/tasks.json containing the watch task. Kept separate from
|
|
117
|
+
* the merge logic so tests can assert the shape without a filesystem.
|
|
118
|
+
*/
|
|
119
|
+
export function generateTasksJson(existingTasks = []) {
|
|
120
|
+
const tasks = [...existingTasks];
|
|
121
|
+
const idx = tasks.findIndex(t => t.label === WATCH_TASK_LABEL);
|
|
122
|
+
const task = watchBuildTask();
|
|
123
|
+
if (idx >= 0)
|
|
124
|
+
tasks[idx] = task;
|
|
125
|
+
else
|
|
126
|
+
tasks.push(task);
|
|
127
|
+
return `${JSON.stringify({ version: '2.0.0', tasks }, null, 2)}\n`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Read-merge-write .vscode/tasks.json with the watch task (by label), so user
|
|
131
|
+
* edits and the framework debug writer's tasks survive. Mirrors the Zephyr
|
|
132
|
+
* debug-config merge semantics.
|
|
133
|
+
*/
|
|
134
|
+
function writeTasksJson(vscodeDir) {
|
|
135
|
+
const tasksPath = path.join(vscodeDir, 'tasks.json');
|
|
136
|
+
let existing = [];
|
|
137
|
+
if (fs.existsSync(tasksPath)) {
|
|
138
|
+
try {
|
|
139
|
+
const doc = JSON.parse(fs.readFileSync(tasksPath, 'utf-8'));
|
|
140
|
+
const tasks = doc.tasks;
|
|
141
|
+
if (Array.isArray(tasks)) {
|
|
142
|
+
existing = tasks.filter((t) => !!t && typeof t === 'object');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// malformed — start fresh
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
fs.writeFileSync(tasksPath, generateTasksJson(existing), 'utf-8');
|
|
150
|
+
return tasksPath;
|
|
151
|
+
}
|
|
152
|
+
// -- install -----------------------------------------------------------------
|
|
153
|
+
/** All files under `dir`, as paths relative to `dir`. */
|
|
154
|
+
function listFilesRecursive(dir) {
|
|
155
|
+
const out = [];
|
|
156
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
157
|
+
if (entry.isDirectory()) {
|
|
158
|
+
for (const nested of listFilesRecursive(path.join(dir, entry.name))) {
|
|
159
|
+
out.push(path.join(entry.name, nested));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
out.push(entry.name);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Whether <outDir> has an `npm run dev` script for the watch task to drive.
|
|
170
|
+
* The task is skipped when it doesn't (e.g. the monorepo root or hand-made
|
|
171
|
+
* projects), because a task referencing a missing script just errors on run.
|
|
172
|
+
*/
|
|
173
|
+
function hasDevScript(outDir) {
|
|
174
|
+
try {
|
|
175
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(outDir, 'package.json'), 'utf-8'));
|
|
176
|
+
const scripts = pkg.scripts;
|
|
177
|
+
return typeof scripts?.dev === 'string';
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Copy the bundled extensions into <outDir>/.vscode/extensions/, then write the
|
|
185
|
+
* companion .vscode/extensions.json and — when the project has a `dev` watch
|
|
186
|
+
* script — the .vscode/tasks.json watch task. Returns the absolute paths
|
|
187
|
+
* written, or [] when the extension assets are missing (warns, never throws).
|
|
188
|
+
* `assetsRoot` overrides the bundled-asset location (tests).
|
|
189
|
+
*/
|
|
190
|
+
export function writeEditorIntegration(outDir, assetsRoot) {
|
|
191
|
+
const vscodeDir = path.join(outDir, '.vscode');
|
|
192
|
+
const extensionRoot = path.join(vscodeDir, 'extensions');
|
|
193
|
+
const root = assetsRoot ?? ASSETS_ROOT;
|
|
194
|
+
const written = [];
|
|
195
|
+
let copiedAny = false;
|
|
196
|
+
for (const ext of BUNDLED_EXTENSIONS) {
|
|
197
|
+
const src = path.join(root, ext.dir);
|
|
198
|
+
if (!fs.existsSync(path.join(src, 'package.json'))) {
|
|
199
|
+
console.warn(`! Editor integration: ${ext.dir} extension assets not found at ${src} — skipped`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const dest = path.join(extensionRoot, ext.dir);
|
|
203
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
204
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
205
|
+
for (const rel of listFilesRecursive(dest))
|
|
206
|
+
written.push(path.join(dest, rel));
|
|
207
|
+
copiedAny = true;
|
|
208
|
+
}
|
|
209
|
+
if (!copiedAny)
|
|
210
|
+
return [];
|
|
211
|
+
const extensionsJsonPath = path.join(vscodeDir, 'extensions.json');
|
|
212
|
+
fs.writeFileSync(extensionsJsonPath, generateExtensionsJson(), 'utf-8');
|
|
213
|
+
written.push(extensionsJsonPath);
|
|
214
|
+
if (hasDevScript(outDir)) {
|
|
215
|
+
written.push(writeTasksJson(vscodeDir));
|
|
216
|
+
}
|
|
217
|
+
return written;
|
|
218
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function generateEslintRules(_options:
|
|
1
|
+
import type { CreateProjectOptions } from "./templates.js";
|
|
2
|
+
export declare function generateEslintRules(_options: CreateProjectOptions): string;
|
|
@@ -53,6 +53,14 @@ export declare function frameworkTargetProfile(target: TargetProfileInput, frame
|
|
|
53
53
|
* common framework is offered first in the prompt.
|
|
54
54
|
*/
|
|
55
55
|
export declare function frameworksForTarget(target: BoardLike): FrameworkCatalogEntry[];
|
|
56
|
+
/**
|
|
57
|
+
* Whether `frameworkId` is actually offered for `target`: compatible with the
|
|
58
|
+
* board's architecture AND installable. Auto-picking narrows via
|
|
59
|
+
* frameworksForTarget, but an explicit `--framework` bypasses that narrowing —
|
|
60
|
+
* callers accepting one must reject anything this returns false for (e.g.
|
|
61
|
+
* `--framework arduino` on the Zephyr-only xiao-nrf52840).
|
|
62
|
+
*/
|
|
63
|
+
export declare function frameworkCompatibleWithTarget(target: BoardLike, frameworkId: string): boolean;
|
|
56
64
|
export type PackageManager = "npm" | "pnpm" | "yarn";
|
|
57
65
|
/**
|
|
58
66
|
* Detect the package manager for a directory. Priority:
|
|
@@ -21,7 +21,7 @@ export const FRAMEWORK_CATALOG = [
|
|
|
21
21
|
* Architecture → compatible framework ids. Derived from each framework
|
|
22
22
|
* package's framework.manifest.ts `profile.targets`:
|
|
23
23
|
* - arduino: avr, esp32 family, rp2040/rp2350, samd, stm32
|
|
24
|
-
* - zephyr: nrf52 (xiao_ble), esp32, esp32s3
|
|
24
|
+
* - zephyr: nrf52 (xiao_ble), esp32 family (esp32, esp32s3, esp32c3, esp32c6)
|
|
25
25
|
* - native: desktop only
|
|
26
26
|
* Unknown embedded architectures fall back to [arduino] (the broadest core).
|
|
27
27
|
*/
|
|
@@ -30,11 +30,15 @@ const ARCHITECTURE_FRAMEWORKS = {
|
|
|
30
30
|
esp32: ["arduino", "zephyr"],
|
|
31
31
|
esp32s2: ["arduino"],
|
|
32
32
|
esp32s3: ["arduino", "zephyr"],
|
|
33
|
-
esp32c3: ["arduino"],
|
|
34
|
-
esp32c6: ["arduino"],
|
|
33
|
+
esp32c3: ["arduino", "zephyr"],
|
|
34
|
+
esp32c6: ["arduino", "zephyr"],
|
|
35
35
|
rp2040: ["arduino"],
|
|
36
36
|
rp2350: ["arduino"],
|
|
37
37
|
samd: ["arduino"],
|
|
38
|
+
// Per-chip key (esp32c3/c6 style). The generic 'stm32' entry stays
|
|
39
|
+
// ["arduino"] for future STM32duino support; the F411 Black Pill is
|
|
40
|
+
// Zephyr-only today.
|
|
41
|
+
stm32f411: ["zephyr"],
|
|
38
42
|
stm32: ["arduino"],
|
|
39
43
|
nrf52: ["zephyr"],
|
|
40
44
|
};
|
|
@@ -66,8 +70,17 @@ const FRAMEWORK_TOOLCHAIN = {
|
|
|
66
70
|
const ZEPHYR_BOARD_IDS = {
|
|
67
71
|
"esp32-devkit": "esp32_devkitc/esp32/procpu",
|
|
68
72
|
esp32s3: "esp32s3_devkitc/esp32s3/procpu",
|
|
69
|
-
//
|
|
70
|
-
//
|
|
73
|
+
// Single-variant RISC-V board — the bare id is also accepted, but the
|
|
74
|
+
// qualified form is kept for consistency (verified against Zephyr 4.3
|
|
75
|
+
// boards/espressif/esp32c3_devkitm).
|
|
76
|
+
esp32c3: "esp32c3_devkitm/esp32c3",
|
|
77
|
+
// hpcore/lpcore cpucluster variants — the qualified form is required (the
|
|
78
|
+
// bare id is rejected); hpcore is the application core.
|
|
79
|
+
esp32c6: "esp32c6_devkitc/esp32c6/hpcore",
|
|
80
|
+
// First STM32 target — WeAct Black Pill V2.0 (STM32F411CEU6). Single
|
|
81
|
+
// variant; qualified for consistency with every other catalog target.
|
|
82
|
+
"blackpill-f411ce": "blackpill_f411ce/stm32f411xe",
|
|
83
|
+
// nRF52840 (single core), base (non-sense) variant.
|
|
71
84
|
"xiao-nrf52840": "xiao_ble/nrf52840",
|
|
72
85
|
};
|
|
73
86
|
/**
|
|
@@ -105,6 +118,16 @@ export function frameworksForTarget(target) {
|
|
|
105
118
|
// any id that has no catalog entry (defensive — keeps the prompt clean).
|
|
106
119
|
return FRAMEWORK_CATALOG.filter((entry) => ids.includes(entry.id));
|
|
107
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Whether `frameworkId` is actually offered for `target`: compatible with the
|
|
123
|
+
* board's architecture AND installable. Auto-picking narrows via
|
|
124
|
+
* frameworksForTarget, but an explicit `--framework` bypasses that narrowing —
|
|
125
|
+
* callers accepting one must reject anything this returns false for (e.g.
|
|
126
|
+
* `--framework arduino` on the Zephyr-only xiao-nrf52840).
|
|
127
|
+
*/
|
|
128
|
+
export function frameworkCompatibleWithTarget(target, frameworkId) {
|
|
129
|
+
return frameworksForTarget(target).some((f) => f.id === frameworkId && f.installable);
|
|
130
|
+
}
|
|
108
131
|
/**
|
|
109
132
|
* Detect the package manager for a directory. Priority:
|
|
110
133
|
* 1. package.json#packageManager field (the strongest signal, Corepack-style)
|
package/dist/create/index.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget,
|
|
2
|
-
export type { KnownTarget, KnownBoard, ScaffoldProjectResult } from './
|
|
3
|
-
export { FRAMEWORK_CATALOG, frameworksForTarget, frameworkCatalogEntry, detectPackageManager, frameworkTargetProfile } from './framework-catalog.js';
|
|
1
|
+
export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget, printCreateNextSteps } from './scaffold.js';
|
|
2
|
+
export type { KnownTarget, KnownBoard, ScaffoldProjectResult } from './scaffold.js';
|
|
3
|
+
export { FRAMEWORK_CATALOG, frameworksForTarget, frameworkCompatibleWithTarget, frameworkCatalogEntry, detectPackageManager, frameworkTargetProfile } from './framework-catalog.js';
|
|
4
4
|
export type { FrameworkCatalogEntry, BoardLike, PackageManager, FrameworkTargetProfile, TargetProfileInput } from './framework-catalog.js';
|
|
5
5
|
export { installProjectDependencies, __setProjectInstallRunnerForTest } from './install-deps.js';
|
|
6
6
|
export type { ProjectInstallResult } from './install-deps.js';
|
|
7
|
-
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, } from './
|
|
8
|
-
export type {
|
|
9
|
-
export {
|
|
7
|
+
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEditorconfig, generateEslintConfig, } from './templates.js';
|
|
8
|
+
export type { CreateProjectOptions } from './templates.js';
|
|
9
|
+
export { runCreateWizard } from './wizard.js';
|
|
10
|
+
export { generateFrameworkDebugArtifacts } from './debug-artifacts.js';
|
|
11
|
+
export type { FrameworkDebugArtifactsOptions, FrameworkModuleLoader } from './debug-artifacts.js';
|
|
12
|
+
export { generateExtensionsJson, generateTasksJson, watchBuildTask, writeEditorIntegration, bundledExtensionSourceDir, typecadUiExtensionSourceDir, TYPECAD_UI_EXTENSION_ID, TYPECAD_DEBUG_EXTENSION_ID, WATCH_TASK_LABEL, } from './editor-integration.js';
|
|
10
13
|
export { scaffoldBoardPackages } from './board-codegen.js';
|
|
11
14
|
export type { ScaffoldBoardResult } from './board-codegen.js';
|
|
12
15
|
export { generateFrameworkChecklist } from './board-checklist.js';
|
package/dist/create/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget,
|
|
2
|
-
export { FRAMEWORK_CATALOG, frameworksForTarget, frameworkCatalogEntry, detectPackageManager, frameworkTargetProfile } from './framework-catalog.js';
|
|
1
|
+
export { scaffoldProject, normalizeProjectName, KNOWN_TARGETS, KNOWN_BOARDS, registerKnownTarget, printCreateNextSteps } from './scaffold.js';
|
|
2
|
+
export { FRAMEWORK_CATALOG, frameworksForTarget, frameworkCompatibleWithTarget, frameworkCatalogEntry, detectPackageManager, frameworkTargetProfile } from './framework-catalog.js';
|
|
3
3
|
export { installProjectDependencies, __setProjectInstallRunnerForTest } from './install-deps.js';
|
|
4
|
-
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEslintConfig, } from './
|
|
5
|
-
export {
|
|
4
|
+
export { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEditorconfig, generateEslintConfig, } from './templates.js';
|
|
5
|
+
export { runCreateWizard } from './wizard.js';
|
|
6
|
+
export { generateFrameworkDebugArtifacts } from './debug-artifacts.js';
|
|
7
|
+
export { generateExtensionsJson, generateTasksJson, watchBuildTask, writeEditorIntegration, bundledExtensionSourceDir, typecadUiExtensionSourceDir, TYPECAD_UI_EXTENSION_ID, TYPECAD_DEBUG_EXTENSION_ID, WATCH_TASK_LABEL, } from './editor-integration.js';
|
|
6
8
|
// Board codegen tool (`cuttlefish board add`)
|
|
7
9
|
export { scaffoldBoardPackages } from './board-codegen.js';
|
|
8
10
|
export { generateFrameworkChecklist } from './board-checklist.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ArchitectureIdentifier } from "../api/index.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { CreateProjectOptions } from "./templates.js";
|
|
3
3
|
export interface KnownTarget {
|
|
4
4
|
id: string;
|
|
5
5
|
displayName: string;
|
|
@@ -28,9 +28,10 @@ export declare function normalizeProjectName(name: string): string;
|
|
|
28
28
|
export interface ScaffoldProjectResult {
|
|
29
29
|
createdFiles: string[];
|
|
30
30
|
outDir: string;
|
|
31
|
-
options:
|
|
31
|
+
options: CreateProjectOptions;
|
|
32
32
|
}
|
|
33
|
-
export declare function scaffoldProject(options:
|
|
34
|
-
export declare function
|
|
33
|
+
export declare function scaffoldProject(options: CreateProjectOptions, outDir?: string): ScaffoldProjectResult;
|
|
34
|
+
export declare function printCreateNextSteps(options: CreateProjectOptions, outDir: string, opts?: {
|
|
35
35
|
installed?: boolean;
|
|
36
|
+
debugProfile?: boolean;
|
|
36
37
|
}): void;
|
|
@@ -1,8 +1,9 @@
|
|
|
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, generateStarterTest, generateStarterSim, generateGitignore, generateBoardForwardingFile, generateEslintConfig, } from "./
|
|
4
|
+
import { generateProjectPackageJson, generateProjectTsconfig, generateProjectConfig, generateProjectEnvDts, generateStarterSketch, generateStarterTest, generateStarterSim, generateGitignore, generateEditorconfig, generateBoardForwardingFile, generateEslintConfig, } from "./templates.js";
|
|
5
5
|
import { generateEslintRules } from "./eslint-rules-template.js";
|
|
6
|
+
import { writeEditorIntegration } from "./editor-integration.js";
|
|
6
7
|
const _knownTargets = [
|
|
7
8
|
{
|
|
8
9
|
id: 'native',
|
|
@@ -74,6 +75,28 @@ const _knownTargets = [
|
|
|
74
75
|
buildTarget: 'rp2040:rp2040:rpipico2',
|
|
75
76
|
mcu: 'rp2350',
|
|
76
77
|
},
|
|
78
|
+
{
|
|
79
|
+
id: 'xiao-nrf52840',
|
|
80
|
+
displayName: 'XIAO nRF52840',
|
|
81
|
+
isNative: false,
|
|
82
|
+
architecture: 'nrf52',
|
|
83
|
+
boardPackage: '@typecad/board-xiao-nrf52840',
|
|
84
|
+
// Zephyr-only target: the build target is the `west build -b` board id,
|
|
85
|
+
// not an Arduino FQBN (frameworkTargetProfile resolves it for Zephyr).
|
|
86
|
+
buildTarget: 'xiao_ble/nrf52840',
|
|
87
|
+
mcu: 'nrf52840',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'blackpill-f411ce',
|
|
91
|
+
displayName: 'Black Pill (STM32F411)',
|
|
92
|
+
isNative: false,
|
|
93
|
+
architecture: 'stm32f411',
|
|
94
|
+
boardPackage: '@typecad/board-blackpill-f411ce',
|
|
95
|
+
// Zephyr-only target: the build target is the `west build -b` board id,
|
|
96
|
+
// not an Arduino FQBN (frameworkTargetProfile resolves it for Zephyr).
|
|
97
|
+
buildTarget: 'blackpill_f411ce/stm32f411xe',
|
|
98
|
+
mcu: 'stm32f411',
|
|
99
|
+
},
|
|
77
100
|
];
|
|
78
101
|
export function registerKnownTarget(target) {
|
|
79
102
|
const existing = _knownTargets.findIndex(t => t.id === target.id);
|
|
@@ -125,6 +148,11 @@ export function scaffoldProject(options, outDir) {
|
|
|
125
148
|
writeFile('.cuttlefish/eslint.config.mjs', generateEslintConfig(options));
|
|
126
149
|
writeFile('.cuttlefish/eslint-transpiler-rules.mjs', generateEslintRules(options));
|
|
127
150
|
writeFile('.gitignore', generateGitignore(options));
|
|
151
|
+
writeFile('.editorconfig', generateEditorconfig(options));
|
|
152
|
+
// Editor integration: workspace-bundled VS Code extension for .ui syntax
|
|
153
|
+
// highlighting (best-effort — warns and skips if the assets are missing).
|
|
154
|
+
for (const file of writeEditorIntegration(resolvedOutDir))
|
|
155
|
+
createdFiles.push(file);
|
|
128
156
|
if (options.boardPackage) {
|
|
129
157
|
const boardFilePath = path.join(cuttlefishDir, 'board.ts');
|
|
130
158
|
fs.writeFileSync(boardFilePath, generateBoardForwardingFile(options.boardPackage), 'utf-8');
|
|
@@ -156,7 +184,7 @@ export function scaffoldProject(options, outDir) {
|
|
|
156
184
|
}
|
|
157
185
|
return { createdFiles, outDir: resolvedOutDir, options };
|
|
158
186
|
}
|
|
159
|
-
export function
|
|
187
|
+
export function printCreateNextSteps(options, outDir, opts = {}) {
|
|
160
188
|
const relativeDir = path.relative(process.cwd(), outDir) || '.';
|
|
161
189
|
console.log();
|
|
162
190
|
console.log(chalk.cyan(`⤳ Cuttlefish`));
|
|
@@ -168,6 +196,14 @@ export function printInitNextSteps(options, outDir, opts = {}) {
|
|
|
168
196
|
console.log(chalk.dim(` npm install`));
|
|
169
197
|
}
|
|
170
198
|
console.log(` ${chalk.cyan("npm run compile")}`);
|
|
199
|
+
if (opts.debugProfile) {
|
|
200
|
+
console.log();
|
|
201
|
+
console.log(chalk.bold.white("To debug (VS Code):"));
|
|
202
|
+
console.log(` ${chalk.cyan("open the folder and press F5")} ${chalk.dim("(builds + flashes, then attaches GDB)")}`);
|
|
203
|
+
}
|
|
204
|
+
console.log();
|
|
205
|
+
console.log(chalk.bold.white("To edit .ui files (VS Code):"));
|
|
206
|
+
console.log(` ${chalk.cyan("open the folder and approve the workspace extension")} ${chalk.dim("(adds .ui syntax highlighting)")}`);
|
|
171
207
|
if (!options.isNative) {
|
|
172
208
|
const portHint = process.platform === 'win32' ? 'COM4' : '/dev/ttyACM0';
|
|
173
209
|
console.log();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ArchitectureIdentifier } from '../api/index.js';
|
|
2
|
+
export interface CreateProjectOptions {
|
|
3
|
+
projectName: string;
|
|
4
|
+
targetId: string;
|
|
5
|
+
targetDisplayName: string;
|
|
6
|
+
isNative: boolean;
|
|
7
|
+
architecture?: ArchitectureIdentifier;
|
|
8
|
+
boardPackage?: string;
|
|
9
|
+
frameworkPackage: string;
|
|
10
|
+
framework: string;
|
|
11
|
+
buildTarget?: string;
|
|
12
|
+
mcu?: string;
|
|
13
|
+
baudRate?: number;
|
|
14
|
+
includeSketch: boolean;
|
|
15
|
+
toolchainType?: string;
|
|
16
|
+
/** Extra frameworkData fields (e.g. `{ target: 'esp32s3' }` for framework-esp32). */
|
|
17
|
+
frameworkData?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export declare function generateProjectPackageJson(options: CreateProjectOptions): string;
|
|
20
|
+
export declare function generateProjectTsconfig(options: CreateProjectOptions): string;
|
|
21
|
+
export declare function generateProjectConfig(options: CreateProjectOptions): string;
|
|
22
|
+
export declare function generateProjectEnvDts(options: CreateProjectOptions): string;
|
|
23
|
+
export declare function generateStarterSketch(options: CreateProjectOptions): string;
|
|
24
|
+
export declare function generateStarterTest(_options: CreateProjectOptions): string;
|
|
25
|
+
export declare function generateStarterSim(options: CreateProjectOptions): string;
|
|
26
|
+
export declare function generateBoardForwardingFile(boardPackage: string): string;
|
|
27
|
+
export declare function generateGitignore(_options: CreateProjectOptions): string;
|
|
28
|
+
export declare function generateEditorconfig(_options: CreateProjectOptions): string;
|
|
29
|
+
export declare function generateEslintConfig(_options: CreateProjectOptions): string;
|
|
@@ -149,7 +149,6 @@ const config = {
|
|
|
149
149
|
|
|
150
150
|
// Output options
|
|
151
151
|
output: {
|
|
152
|
-
optimize: 'speed',
|
|
153
152
|
outDir: './out',
|
|
154
153
|
},
|
|
155
154
|
};
|
|
@@ -198,7 +197,6 @@ const config: CuttlefishConfig = {
|
|
|
198
197
|
// Output / build options
|
|
199
198
|
output: {
|
|
200
199
|
framework: '${options.framework}',
|
|
201
|
-
optimize: 'size',
|
|
202
200
|
outDir: './out',
|
|
203
201
|
},
|
|
204
202
|
|
|
@@ -559,6 +557,21 @@ dist/
|
|
|
559
557
|
.cuttlefish/eslint-transpiler-rules.mjs
|
|
560
558
|
`;
|
|
561
559
|
}
|
|
560
|
+
export function generateEditorconfig(_options) {
|
|
561
|
+
return `# Auto-generated by 'cuttlefish create'. Edit to customise your build.
|
|
562
|
+
root = true
|
|
563
|
+
|
|
564
|
+
[*]
|
|
565
|
+
charset = utf-8
|
|
566
|
+
end_of_line = lf
|
|
567
|
+
insert_final_newline = true
|
|
568
|
+
trim_trailing_whitespace = true
|
|
569
|
+
|
|
570
|
+
[*.{ts,js,mjs,cjs,json,css,ui,md,yml}]
|
|
571
|
+
indent_style = space
|
|
572
|
+
indent_size = 2
|
|
573
|
+
`;
|
|
574
|
+
}
|
|
562
575
|
export function generateEslintConfig(_options) {
|
|
563
576
|
// `no-restricted-syntax` selectors are generated from LINT_RULES
|
|
564
577
|
// (packages/cuttlefish/src/ir/feature-registry.ts), the single source of
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CreateProjectOptions } from "./templates.js";
|
|
2
|
+
export declare function runCreateWizard(partialOptions?: {
|
|
3
|
+
projectName?: string;
|
|
4
|
+
board?: string;
|
|
5
|
+
framework?: string;
|
|
6
|
+
baud?: number;
|
|
7
|
+
noSketch?: boolean;
|
|
8
|
+
}): Promise<CreateProjectOptions | null>;
|