@typecad/framework-zephyr 1.0.0-alpha.10 → 1.0.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/chips/esp32.js +12 -0
  2. package/dist/chips/types.d.ts +30 -0
  3. package/dist/chips/xiao-ble.js +6 -0
  4. package/dist/display/gfx.d.ts +12 -3
  5. package/dist/display/gfx.js +130 -17
  6. package/dist/display/profiles.js +13 -0
  7. package/dist/display/ui-adapter.js +6 -0
  8. package/dist/doctor.d.ts +3 -3
  9. package/dist/doctor.js +56 -29
  10. package/dist/dt-config/kconfig.d.ts +3 -0
  11. package/dist/dt-config/kconfig.js +18 -0
  12. package/dist/dt-config/overlay.js +5 -0
  13. package/dist/framework.manifest.js +37 -14
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +5 -0
  16. package/dist/licenses.d.ts +59 -0
  17. package/dist/licenses.js +347 -0
  18. package/dist/lowering/dac.d.ts +15 -0
  19. package/dist/lowering/dac.js +69 -0
  20. package/dist/lowering/fs.d.ts +16 -0
  21. package/dist/lowering/fs.js +121 -0
  22. package/dist/lowering/hwtimer.d.ts +15 -0
  23. package/dist/lowering/hwtimer.js +84 -0
  24. package/dist/lowering/index.d.ts +4 -1
  25. package/dist/lowering/index.js +12 -3
  26. package/dist/strategy.js +186 -14
  27. package/dist/toolchain/compat.js +10 -1
  28. package/dist/toolchain/env-check.d.ts +93 -0
  29. package/dist/toolchain/env-check.js +190 -0
  30. package/dist/toolchain/scaffold.js +3 -0
  31. package/dist/toolchain/west-discover.d.ts +11 -3
  32. package/dist/toolchain/west-discover.js +80 -6
  33. package/dist/toolchain/west-spawn.js +15 -0
  34. package/package.json +4 -4
  35. package/src/chips/esp32.ts +12 -0
  36. package/src/chips/types.ts +29 -0
  37. package/src/chips/xiao-ble.ts +6 -0
  38. package/src/display/gfx.ts +135 -19
  39. package/src/display/profiles.ts +13 -0
  40. package/src/display/ui-adapter.ts +5 -0
  41. package/src/doctor.ts +77 -56
  42. package/src/dt-config/kconfig.ts +19 -0
  43. package/src/dt-config/overlay.ts +5 -0
  44. package/src/framework.manifest.ts +38 -14
  45. package/src/index.ts +6 -0
  46. package/src/licenses.ts +425 -0
  47. package/src/lowering/dac.ts +82 -0
  48. package/src/lowering/fs.ts +127 -0
  49. package/src/lowering/hwtimer.ts +101 -0
  50. package/src/lowering/index.ts +9 -2
  51. package/src/strategy.ts +180 -14
  52. package/src/toolchain/compat.ts +154 -145
  53. package/src/toolchain/env-check.ts +285 -0
  54. package/src/toolchain/scaffold.ts +3 -0
  55. package/src/toolchain/west-discover.ts +88 -8
  56. package/src/toolchain/west-spawn.ts +15 -0
@@ -10,15 +10,17 @@
10
10
  // Discovery cascade (first usable wins):
11
11
  // 1. `west` already on PATH (env already activated / global install).
12
12
  // 2. $ZEPHYR_BASE venv: ${ZEPHYR_BASE}/../.venv/<python> -m west.
13
- // 3. Well-known workspace layouts: ~/zephyrproject/.venv, /opt/zephyrproject/.
13
+ // 3. micromamba env from @typecad/zephyr-installer (invoked via `micromamba run`,
14
+ // so cuttlefish builds work with NO manual activation).
15
+ // 4. Well-known workspace layouts: ~/zephyrproject/.venv, /opt/zephyrproject/.
14
16
  // venv, etc.
15
- // 4. System pythons (`python`, `python3`, `py`) via `-m west`.
17
+ // 5. System pythons (`python`, `python3`, `py`) via `-m west`.
16
18
  //
17
19
  // Leaner than the ESP-IDF equivalent: west needs no env sourcing (no 15s
18
20
  // export.sh) — only the right interpreter + ZEPHYR_BASE.
19
21
  // ---------------------------------------------------------------------------
20
22
 
21
- import { existsSync, realpathSync, statSync } from 'node:fs';
23
+ import { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';
22
24
  import { dirname, join } from 'node:path';
23
25
  import { homedir } from 'node:os';
24
26
  import { spawnSync } from 'node:child_process';
@@ -65,15 +67,21 @@ function westOnPath(cmd: string): boolean {
65
67
  * `pythonExecutable -m west`.
66
68
  */
67
69
  export interface WestInstall {
68
- mode: 'launcher' | 'module';
70
+ mode: 'launcher' | 'module' | 'micromamba';
69
71
  /** Absolute path to a `west` launcher (mode 'launcher') or undefined. */
70
72
  westExecutable?: string;
71
73
  /** Absolute path to a Python interpreter with west installed (mode 'module'). */
72
74
  pythonExecutable?: string;
73
75
  /** Absolute path to the Zephyr SDK root (for $ZEPHYR_BASE), if found. */
74
76
  zephyrBase?: string;
77
+ /** mode 'micromamba': path to the micromamba binary (for `micromamba run -n …`). */
78
+ micromambaExe?: string;
79
+ /** mode 'micromamba': the conda env name (default 'zephyr'). */
80
+ envName?: string;
81
+ /** mode 'micromamba': MAMBA_ROOT_PREFIX, injected so micromamba finds its envs. */
82
+ mambaRootPrefix?: string;
75
83
  /** Which discovery strategy found this install. */
76
- source: 'path' | 'zephyr-base-venv' | 'well-known' | 'system-python';
84
+ source: 'path' | 'zephyr-base-venv' | 'well-known' | 'system-python' | 'micromamba';
77
85
  }
78
86
 
79
87
  /** True if `dir` looks like a Zephyr SDK root: has CMakeLists.txt and the
@@ -128,7 +136,77 @@ export function discoverFromZephyrBase(): WestInstall | null {
128
136
  };
129
137
  }
130
138
 
131
- // ── Strategy 3: well-known workspace layouts ───────────────────────────────
139
+ // ── Strategy 3: micromamba env (the @typecad/zephyr-installer install) ─────
140
+
141
+ // Locate the micromamba binary + root prefix. The installer downloads
142
+ // micromamba to $MAMBA_ROOT_PREFIX/bin (POSIX) or Library/bin (Windows); the
143
+ // root defaults to ~/micromamba. Returns null if the binary isn't present
144
+ // (the installer hasn't run on this machine).
145
+ function findMicromamba(): { exe: string; rootPrefix: string } | null {
146
+ const root = process.env.MAMBA_ROOT_PREFIX || join(homedir(), 'micromamba');
147
+ const exe = IS_WIN
148
+ ? join(root, 'Library', 'bin', 'micromamba.exe')
149
+ : join(root, 'bin', 'micromamba');
150
+ return existsSync(exe) ? { exe, rootPrefix: root } : null;
151
+ }
152
+
153
+ /**
154
+ * The micromamba env created by `@typecad/zephyr-installer`. The env's west
155
+ * lives at envs/<name>/bin/west (POSIX) or Scripts/west.exe (Windows). Found
156
+ * installs are invoked via `micromamba run -n <name> west …` (see
157
+ * west-spawn.ts), which sets up the env's full PATH (cmake/ninja/dtc) AND runs
158
+ * the activation hook (ZEPHYR_BASE / ZEPHYR_SDK_INSTALL_DIR) — so cuttlefish
159
+ * builds work with NO manual `micromamba activate`. This is what makes a fresh
160
+ * `cuttlefish build` succeed in any project without the user activating.
161
+ *
162
+ * Env name defaults to "zephyr"; override via TYPECAD_ZEPHYR_ENV. File-check
163
+ * based (no spawn) so it's cheap to run on every cuttlefish invocation.
164
+ */
165
+ /** Read a TYPECAD_ZEPHYR_* value from the installer-written env-vars file in
166
+ * a micromamba env. Handles .sh (export VAR="val"), .bat (set "VAR=val"),
167
+ * and .ps1 ($env:VAR = "val"). Returns undefined if absent/unreadable. */
168
+ function readMicromambaEnvVar(envDir: string, varName: string): string | undefined {
169
+ const candidates = IS_WIN
170
+ ? [join(envDir, 'etc', 'conda', 'env-vars.ps1'), join(envDir, 'etc', 'conda', 'env-vars.bat')]
171
+ : [join(envDir, 'etc', 'conda', 'env-vars.sh')];
172
+ for (const f of candidates) {
173
+ if (!existsSync(f)) continue;
174
+ try {
175
+ const text = readFileSync(f, 'utf8');
176
+ // .sh/.ps1: VAR = "value" (quoted value after =).
177
+ let m = text.match(new RegExp(`${varName}\\s*=\\s*"([^"]+)"`));
178
+ if (m) return m[1];
179
+ // .bat: set "VAR=value" (value after VAR= inside quotes).
180
+ m = text.match(new RegExp(`${varName}=([^"\\r\\n]+)"`));
181
+ if (m) return m[1].trim();
182
+ } catch { /* ignore unreadable */ }
183
+ }
184
+ return undefined;
185
+ }
186
+
187
+ export function discoverFromMicromamba(
188
+ envName: string = process.env.TYPECAD_ZEPHYR_ENV || 'zephyr',
189
+ ): WestInstall | null {
190
+ const mm = findMicromamba();
191
+ if (!mm) return null;
192
+ const envDir = join(mm.rootPrefix, 'envs', envName);
193
+ const westExe = join(envDir, IS_WIN ? 'Scripts' : 'bin', IS_WIN ? 'west.exe' : 'west');
194
+ if (!existsSync(envDir) || !existsSync(westExe)) return null;
195
+ // Read ZEPHYR_BASE from the installer's env-vars so the compat check (and
196
+ // anything else in the cuttlefish process) can detect the Zephyr version
197
+ // WITHOUT activation — micromamba run sets it only inside the west subprocess.
198
+ const zb = readMicromambaEnvVar(envDir, 'TYPECAD_ZEPHYR_BASE');
199
+ return {
200
+ mode: 'micromamba',
201
+ micromambaExe: mm.exe,
202
+ envName,
203
+ mambaRootPrefix: mm.rootPrefix,
204
+ zephyrBase: zb && isZephyrBase(zb) ? zb : undefined,
205
+ source: 'micromamba',
206
+ };
207
+ }
208
+
209
+ // ── Strategy 4: well-known workspace layouts ───────────────────────────────
132
210
 
133
211
  /** Candidate Zephyr workspace directories. Each may contain both `.venv/`
134
212
  * and `zephyr/` (the SDK). Exported for test injection. */
@@ -169,7 +247,7 @@ export function discoverFromWellKnown(
169
247
  return null;
170
248
  }
171
249
 
172
- // ── Strategy 4: system pythons via `-m west` ────────────────────────────────
250
+ // ── Strategy 5: system pythons via `-m west` ────────────────────────────────
173
251
 
174
252
  /** Candidate system Python interpreters to probe with `-m west`. */
175
253
  export function systemPythons(): string[] {
@@ -205,7 +283,8 @@ export function resetWestDiscoveryCache(): void {
205
283
  * Try each discovery strategy in order. The first usable install wins.
206
284
  * Result is memoized for the process lifetime (west installs don't move).
207
285
  *
208
- * Order: PATH → $ZEPHYR_BASE venv → well-known workspaces → system pythons.
286
+ * Order: PATH → $ZEPHYR_BASE venv → micromamba env → well-known workspaces →
287
+ * system pythons.
209
288
  * Returns null when no usable west install is found.
210
289
  */
211
290
  export function discoverWest(): WestInstall | null {
@@ -213,6 +292,7 @@ export function discoverWest(): WestInstall | null {
213
292
  const strategies: Array<() => WestInstall | null> = [
214
293
  discoverFromPath,
215
294
  discoverFromZephyrBase,
295
+ discoverFromMicromamba,
216
296
  discoverFromWellKnown,
217
297
  discoverFromSystemPython,
218
298
  ];
@@ -121,6 +121,21 @@ export function westSpawn(
121
121
  // an explicit shell changes arg-quoting semantics on Windows.
122
122
  const { shell: _drop, ...optsWithoutShell } = baseOptions as any;
123
123
 
124
+ if (install.mode === 'micromamba' && install.micromambaExe) {
125
+ // `micromamba run -n <env> west …` sets up the env's full PATH
126
+ // (cmake/ninja/dtc) and runs the activation hook (ZEPHYR_BASE /
127
+ // ZEPHYR_SDK_INSTALL_DIR), so cuttlefish builds work WITHOUT the user
128
+ // activating the env. Inject MAMBA_ROOT_PREFIX so micromamba finds envs.
129
+ const mmEnv = { ...env };
130
+ if (install.mambaRootPrefix) mmEnv.MAMBA_ROOT_PREFIX = install.mambaRootPrefix;
131
+ return {
132
+ command: install.micromambaExe,
133
+ args: ['run', '-n', install.envName ?? 'zephyr', 'west', ...westArgs],
134
+ options: { ...optsWithoutShell, env: mmEnv },
135
+ install,
136
+ };
137
+ }
138
+
124
139
  if (install.mode === 'launcher' && install.westExecutable) {
125
140
  return {
126
141
  command: install.westExecutable,