rinco-pi-hud 1.0.0

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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +18 -0
  3. package/README.md +204 -0
  4. package/docs/CONTRIBUTING.md +110 -0
  5. package/docs/README.zh-CN.md +204 -0
  6. package/docs/footer.md +139 -0
  7. package/extensions/hud/commands/settings.ts +765 -0
  8. package/extensions/hud/config/config-counts.ts +87 -0
  9. package/extensions/hud/config/config.ts +65 -0
  10. package/extensions/hud/config/file-io.ts +128 -0
  11. package/extensions/hud/config/normalize.ts +374 -0
  12. package/extensions/hud/config/persist.ts +277 -0
  13. package/extensions/hud/config/schema.ts +303 -0
  14. package/extensions/hud/footer/format.ts +279 -0
  15. package/extensions/hud/footer/index.ts +543 -0
  16. package/extensions/hud/footer/layout.ts +183 -0
  17. package/extensions/hud/footer/render-labels.ts +305 -0
  18. package/extensions/hud/index.ts +466 -0
  19. package/extensions/hud/segments/extension-status.ts +88 -0
  20. package/extensions/hud/segments/git.ts +384 -0
  21. package/extensions/hud/segments/mcp-status.ts +25 -0
  22. package/extensions/hud/segments/package-version.ts +651 -0
  23. package/extensions/hud/segments/project-state.ts +67 -0
  24. package/extensions/hud/segments/runtime-definitions.ts +695 -0
  25. package/extensions/hud/segments/runtime.ts +167 -0
  26. package/extensions/hud/segments/skill-activity.ts +152 -0
  27. package/extensions/hud/session/context.ts +19 -0
  28. package/extensions/hud/session/lifecycle.ts +60 -0
  29. package/extensions/hud/session/live-context.ts +75 -0
  30. package/extensions/hud/state/index.ts +67 -0
  31. package/extensions/hud/state/project-refresh.ts +104 -0
  32. package/extensions/hud/state/telemetry.ts +261 -0
  33. package/extensions/hud/telemetry/codex-usage/LICENSE +21 -0
  34. package/extensions/hud/telemetry/codex-usage/app-server-client.ts +231 -0
  35. package/extensions/hud/telemetry/codex-usage/format.ts +278 -0
  36. package/extensions/hud/telemetry/codex-usage/index.ts +462 -0
  37. package/extensions/hud/telemetry/codex-usage/normalize.ts +264 -0
  38. package/extensions/hud/telemetry/codex-usage/query.ts +207 -0
  39. package/extensions/hud/telemetry/codex-usage/safety.ts +27 -0
  40. package/extensions/hud/telemetry/codex-usage/types.ts +137 -0
  41. package/extensions/hud/telemetry/format.ts +434 -0
  42. package/extensions/hud/telemetry/token-switch.ts +114 -0
  43. package/extensions/hud/ui/icons.ts +239 -0
  44. package/extensions/hud/ui/style.ts +276 -0
  45. package/package.json +56 -0
@@ -0,0 +1,695 @@
1
+ /**
2
+ * Static runtime/toolchain detection table (Starship `runtime`-module parity).
3
+ *
4
+ * Pulled out of `runtime.ts` because it is >90% data: one entry per
5
+ * language/build-system with its detection rules and version-probe command(s).
6
+ * Detection matching, caching, and the public `detectRuntime`/`readRuntimeInfo`
7
+ * API live in `runtime.ts`; this module only describes *what* each runtime looks
8
+ * like and *how* to ask its toolchain for a version string.
9
+ */
10
+
11
+ import { execFile } from "node:child_process";
12
+ import { promisify } from "node:util";
13
+ import type { DetectionSpec, RuntimeMetadata } from "./runtime.js";
14
+
15
+ const execFileAsync = promisify(execFile);
16
+ const VERSION_TIMEOUT_MS = 2500;
17
+
18
+ type VersionCommand = {
19
+ command: string;
20
+ args?: readonly string[];
21
+ pattern?: RegExp;
22
+ };
23
+
24
+ type RuntimeDef = RuntimeMetadata & {
25
+ priority: number;
26
+ detect: DetectionSpec;
27
+ version: (cwd: string) => Promise<string | undefined>;
28
+ };
29
+
30
+ // --- Version utilities ---
31
+
32
+ async function runVersion(
33
+ command: string,
34
+ args: readonly string[] = [],
35
+ cwd?: string,
36
+ ): Promise<string | undefined> {
37
+ try {
38
+ const { stdout, stderr } = await execFileAsync(command, [...args], {
39
+ cwd,
40
+ timeout: VERSION_TIMEOUT_MS,
41
+ });
42
+ const text =
43
+ `${typeof stdout === "string" ? stdout : String(stdout)}\n${typeof stderr === "string" ? stderr : String(stderr)}`.trim();
44
+ return text || undefined;
45
+ } catch {
46
+ return undefined;
47
+ }
48
+ }
49
+
50
+ function prefixVersion(version: string | undefined): string | undefined {
51
+ if (!version) return undefined;
52
+ return version.startsWith("v") ? version : `v${version}`;
53
+ }
54
+
55
+ function extractVersion(output: string | undefined, pattern?: RegExp): string | undefined {
56
+ if (!output) return undefined;
57
+ const match = output.match(
58
+ pattern ?? /(?:version\s*)?v?([0-9]+(?:\.[0-9A-Za-z][0-9A-Za-z.+_-]*)*)/i,
59
+ );
60
+ return prefixVersion(match?.[1]);
61
+ }
62
+
63
+ function versionFromCommands(
64
+ commands: readonly VersionCommand[],
65
+ ): () => Promise<string | undefined> {
66
+ return async () => {
67
+ for (const { command, args = [], pattern } of commands) {
68
+ const version = extractVersion(await runVersion(command, args), pattern);
69
+ if (version) return version;
70
+ }
71
+ return undefined;
72
+ };
73
+ }
74
+
75
+ function noVersion(): Promise<undefined> {
76
+ return Promise.resolve(undefined);
77
+ }
78
+
79
+ // --- Priority levels ---
80
+ // 10 = build-system runtimes (checked first to avoid language false-positives)
81
+ // 50 = common runtimes (bun, deno, node, python, etc.)
82
+ // 100 = default (everything else, checked in definition order)
83
+
84
+ const PRIORITY_BUILD_SYSTEM = 10;
85
+ const PRIORITY_COMMON = 50;
86
+ const PRIORITY_DEFAULT = 100;
87
+
88
+ // --- Runtime definitions ---
89
+
90
+ const runtimes: RuntimeDef[] = [
91
+ {
92
+ name: "xmake",
93
+ symbol: "",
94
+ style: "bold green",
95
+ priority: PRIORITY_BUILD_SYSTEM,
96
+ detect: { files: ["xmake.lua"] },
97
+ version: versionFromCommands([{ command: "xmake", args: ["--version"] }]),
98
+ },
99
+ {
100
+ name: "maven",
101
+ symbol: "",
102
+ style: "bold bright-cyan",
103
+ priority: PRIORITY_BUILD_SYSTEM,
104
+ detect: { files: ["pom.xml"] },
105
+ version: versionFromCommands([
106
+ { command: "mvn", args: ["--version"], pattern: /Apache Maven\s+([0-9][^\s]*)/i },
107
+ ]),
108
+ },
109
+ {
110
+ name: "gradle",
111
+ symbol: "",
112
+ style: "bold bright-cyan",
113
+ priority: PRIORITY_BUILD_SYSTEM,
114
+ detect: { files: ["build.gradle", "build.gradle.kts"], folders: ["gradle"] },
115
+ version: versionFromCommands([
116
+ { command: "gradle", args: ["--version"], pattern: /Gradle\s+([0-9][^\s]*)/i },
117
+ ]),
118
+ },
119
+ {
120
+ name: "bun",
121
+ symbol: "",
122
+ style: "bold red",
123
+ priority: PRIORITY_COMMON,
124
+ detect: { files: ["bun.lock", "bun.lockb"] },
125
+ version: async () => prefixVersion(await runVersion("bun", ["--version"])),
126
+ },
127
+ {
128
+ name: "deno",
129
+ symbol: "",
130
+ style: "green bold",
131
+ priority: PRIORITY_COMMON,
132
+ detect: { files: ["deno.json", "deno.jsonc", "deno.lock"] },
133
+ version: async () =>
134
+ extractVersion(await runVersion("deno", ["--version"]), /deno\s+([0-9][^\s]*)/i),
135
+ },
136
+ {
137
+ name: "lua",
138
+ symbol: "",
139
+ style: "bold blue",
140
+ priority: PRIORITY_COMMON,
141
+ detect: {
142
+ extensions: ["lua"],
143
+ files: [
144
+ "stylua.toml",
145
+ ".stylua.toml",
146
+ ".luarc.json",
147
+ ".luarc.jsonc",
148
+ "init.lua",
149
+ ".lua-version",
150
+ ],
151
+ folders: ["lua"],
152
+ excludedFiles: ["xmake.lua"],
153
+ },
154
+ version: async () => {
155
+ const lua = await runVersion("lua", ["-v"]);
156
+ const luaMatch = lua?.match(/Lua\s+([0-9][^\s]*)/i);
157
+ if (luaMatch?.[1]) return prefixVersion(luaMatch[1]);
158
+ const luajit = await runVersion("luajit", ["-v"]);
159
+ const luajitMatch = luajit?.match(/LuaJIT\s+([0-9][^\s]*)/i);
160
+ return prefixVersion(luajitMatch?.[1]);
161
+ },
162
+ },
163
+ {
164
+ name: "nodejs",
165
+ symbol: "",
166
+ style: "bold green",
167
+ priority: PRIORITY_COMMON,
168
+ detect: {
169
+ files: ["package.json", ".node-version", ".nvmrc"],
170
+ excludedFiles: ["bunfig.toml", "bun.lock", "bun.lockb"],
171
+ },
172
+ version: async () => prefixVersion(await runVersion("node", ["--version"])),
173
+ },
174
+ {
175
+ name: "python",
176
+ symbol: "",
177
+ style: "yellow bold",
178
+ priority: PRIORITY_COMMON,
179
+ detect: {
180
+ files: [
181
+ "requirements.txt",
182
+ ".python-version",
183
+ "pyproject.toml",
184
+ "Pipfile",
185
+ "setup.py",
186
+ "setup.cfg",
187
+ ],
188
+ },
189
+ version: async () => {
190
+ const python3 = await runVersion("python3", ["--version"]);
191
+ const python3Match = python3?.match(/Python\s+([0-9][^\s]*)/i);
192
+ if (python3Match?.[1]) return prefixVersion(python3Match[1]);
193
+ const python = await runVersion("python", ["--version"]);
194
+ const pythonMatch = python?.match(/Python\s+([0-9][^\s]*)/i);
195
+ return prefixVersion(pythonMatch?.[1]);
196
+ },
197
+ },
198
+ {
199
+ name: "golang",
200
+ symbol: "",
201
+ style: "bold cyan",
202
+ priority: PRIORITY_COMMON,
203
+ detect: { files: ["go.mod"] },
204
+ version: async () =>
205
+ extractVersion(await runVersion("go", ["version"]), /go version go([0-9][^\s]*)/i),
206
+ },
207
+ {
208
+ name: "rust",
209
+ symbol: "󱘗",
210
+ style: "bold red",
211
+ priority: PRIORITY_COMMON,
212
+ detect: { files: ["Cargo.toml"] },
213
+ version: async () =>
214
+ extractVersion(await runVersion("rustc", ["--version"]), /rustc\s+([0-9][^\s]*)/i),
215
+ },
216
+ {
217
+ name: "java",
218
+ symbol: "",
219
+ style: "red dimmed",
220
+ priority: PRIORITY_COMMON,
221
+ detect: { files: [".java-version"] },
222
+ version: async () => {
223
+ const output = await runVersion("java", ["-version"]);
224
+ const quoted = output?.match(/"([0-9][^"]*)"/);
225
+ if (quoted?.[1]) return prefixVersion(quoted[1]);
226
+ const plain = output?.match(/version\s+([0-9][^\s]*)/i);
227
+ return prefixVersion(plain?.[1]);
228
+ },
229
+ },
230
+ {
231
+ name: "ruby",
232
+ symbol: "",
233
+ style: "bold red",
234
+ priority: PRIORITY_COMMON,
235
+ detect: { files: ["Gemfile", ".ruby-version"] },
236
+ version: async () =>
237
+ extractVersion(await runVersion("ruby", ["--version"]), /ruby\s+([0-9][^\s]*)/i),
238
+ },
239
+ {
240
+ name: "php",
241
+ symbol: "",
242
+ style: "147 bold",
243
+ priority: PRIORITY_COMMON,
244
+ detect: { files: ["composer.json"] },
245
+ version: async () =>
246
+ extractVersion(await runVersion("php", ["--version"]), /PHP\s+([0-9][^\s]*)/i),
247
+ },
248
+ {
249
+ name: "buf",
250
+ symbol: "",
251
+ style: "bold blue",
252
+ priority: PRIORITY_DEFAULT,
253
+ detect: { files: ["buf.yaml", "buf.gen.yaml", "buf.work.yaml"] },
254
+ version: versionFromCommands([{ command: "buf", args: ["--version"] }]),
255
+ },
256
+ {
257
+ name: "cmake",
258
+ symbol: "",
259
+ style: "bold blue",
260
+ priority: PRIORITY_DEFAULT,
261
+ detect: { files: ["CMakeLists.txt", "CMakeCache.txt"] },
262
+ version: versionFromCommands([{ command: "cmake", args: ["--version"] }]),
263
+ },
264
+ {
265
+ name: "cpp",
266
+ symbol: "",
267
+ style: "bold 149",
268
+ priority: PRIORITY_DEFAULT,
269
+ detect: { extensions: ["cpp", "cc", "cxx", "c++", "hpp", "hh", "hxx", "h++", "tcc"] },
270
+ version: versionFromCommands([
271
+ { command: "c++", args: ["--version"] },
272
+ { command: "g++", args: ["--version"] },
273
+ { command: "clang++", args: ["--version"] },
274
+ ]),
275
+ },
276
+ {
277
+ name: "c",
278
+ symbol: "",
279
+ style: "bold 149",
280
+ priority: PRIORITY_DEFAULT,
281
+ detect: { extensions: ["c", "h"] },
282
+ version: versionFromCommands([
283
+ { command: "cc", args: ["--version"] },
284
+ { command: "gcc", args: ["--version"] },
285
+ { command: "clang", args: ["--version"] },
286
+ ]),
287
+ },
288
+ {
289
+ name: "cobol",
290
+ symbol: "",
291
+ style: "bold blue",
292
+ priority: PRIORITY_DEFAULT,
293
+ detect: { extensions: ["cbl", "cob", "CBL", "COB"] },
294
+ version: versionFromCommands([{ command: "cobc", args: ["--version"] }]),
295
+ },
296
+ {
297
+ name: "conda",
298
+ symbol: "",
299
+ style: "bold green",
300
+ priority: PRIORITY_DEFAULT,
301
+ detect: { env: (env) => Boolean(env.CONDA_DEFAULT_ENV?.trim()) && !env.PIXI_ENVIRONMENT_NAME },
302
+ version: noVersion,
303
+ },
304
+ {
305
+ name: "crystal",
306
+ symbol: "",
307
+ style: "bold red",
308
+ priority: PRIORITY_DEFAULT,
309
+ detect: { extensions: ["cr"], files: ["shard.yml"] },
310
+ version: versionFromCommands([{ command: "crystal", args: ["--version"] }]),
311
+ },
312
+ {
313
+ name: "dart",
314
+ symbol: "",
315
+ style: "bold blue",
316
+ priority: PRIORITY_DEFAULT,
317
+ detect: {
318
+ extensions: ["dart"],
319
+ files: ["pubspec.yaml", "pubspec.yml", "pubspec.lock"],
320
+ folders: [".dart_tool"],
321
+ },
322
+ version: versionFromCommands([{ command: "dart", args: ["--version"] }]),
323
+ },
324
+ {
325
+ name: "dotnet",
326
+ symbol: "",
327
+ style: "bold blue",
328
+ priority: PRIORITY_DEFAULT,
329
+ detect: {
330
+ extensions: ["csproj", "fsproj", "xproj"],
331
+ files: [
332
+ "global.json",
333
+ "project.json",
334
+ "Directory.Build.props",
335
+ "Directory.Build.targets",
336
+ "Packages.props",
337
+ ],
338
+ },
339
+ version: versionFromCommands([{ command: "dotnet", args: ["--version"] }]),
340
+ },
341
+ {
342
+ name: "elixir",
343
+ symbol: "",
344
+ style: "bold purple",
345
+ priority: PRIORITY_DEFAULT,
346
+ detect: { files: ["mix.exs"] },
347
+ version: versionFromCommands([
348
+ { command: "elixir", args: ["--version"], pattern: /Elixir\s+([0-9][^\s]*)/i },
349
+ ]),
350
+ },
351
+ {
352
+ name: "elm",
353
+ symbol: "",
354
+ style: "cyan bold",
355
+ priority: PRIORITY_DEFAULT,
356
+ detect: {
357
+ extensions: ["elm"],
358
+ files: ["elm.json", "elm-package.json", ".elm-version"],
359
+ folders: ["elm-stuff"],
360
+ },
361
+ version: versionFromCommands([{ command: "elm", args: ["--version"] }]),
362
+ },
363
+ {
364
+ name: "erlang",
365
+ symbol: "",
366
+ style: "bold red",
367
+ priority: PRIORITY_DEFAULT,
368
+ detect: { files: ["rebar.config", "erlang.mk"] },
369
+ version: versionFromCommands([{ command: "erl", args: ["-version"] }]),
370
+ },
371
+ {
372
+ name: "fennel",
373
+ symbol: "",
374
+ style: "bold green",
375
+ priority: PRIORITY_DEFAULT,
376
+ detect: { extensions: ["fnl"] },
377
+ version: versionFromCommands([{ command: "fennel", args: ["--version"] }]),
378
+ },
379
+ {
380
+ name: "fortran",
381
+ symbol: "",
382
+ style: "bold purple",
383
+ priority: PRIORITY_DEFAULT,
384
+ detect: {
385
+ extensions: [
386
+ "f",
387
+ "F",
388
+ "for",
389
+ "FOR",
390
+ "ftn",
391
+ "FTN",
392
+ "f77",
393
+ "F77",
394
+ "f90",
395
+ "F90",
396
+ "f95",
397
+ "F95",
398
+ "f03",
399
+ "F03",
400
+ "f08",
401
+ "F08",
402
+ "f18",
403
+ "F18",
404
+ ],
405
+ files: ["fpm.toml"],
406
+ },
407
+ version: versionFromCommands([
408
+ { command: "gfortran", args: ["--version"] },
409
+ { command: "flang", args: ["--version"] },
410
+ { command: "flang-new", args: ["--version"] },
411
+ ]),
412
+ },
413
+ {
414
+ name: "gleam",
415
+ symbol: "",
416
+ style: "bold #FFAFF3",
417
+ priority: PRIORITY_DEFAULT,
418
+ detect: { extensions: ["gleam"], files: ["gleam.toml"] },
419
+ version: versionFromCommands([{ command: "gleam", args: ["--version"] }]),
420
+ },
421
+ {
422
+ name: "guix_shell",
423
+ symbol: "",
424
+ style: "yellow bold",
425
+ priority: PRIORITY_DEFAULT,
426
+ detect: { env: (env) => Boolean(env.GUIX_ENVIRONMENT?.trim()) },
427
+ version: noVersion,
428
+ },
429
+ {
430
+ name: "haskell",
431
+ symbol: "",
432
+ style: "bold purple",
433
+ priority: PRIORITY_DEFAULT,
434
+ detect: { extensions: ["hs", "cabal", "hs-boot"], files: ["stack.yaml", "cabal.project"] },
435
+ version: versionFromCommands([{ command: "ghc", args: ["--numeric-version"] }]),
436
+ },
437
+ {
438
+ name: "haxe",
439
+ symbol: "",
440
+ style: "bold fg:202",
441
+ priority: PRIORITY_DEFAULT,
442
+ detect: {
443
+ extensions: ["hx", "hxml"],
444
+ files: ["haxelib.json", "hxformat.json", ".haxerc"],
445
+ folders: [".haxelib", "haxe_libraries"],
446
+ },
447
+ version: versionFromCommands([{ command: "haxe", args: ["--version"] }]),
448
+ },
449
+ {
450
+ name: "helm",
451
+ symbol: "",
452
+ style: "bold white",
453
+ priority: PRIORITY_DEFAULT,
454
+ detect: { files: ["helmfile.yaml", "Chart.yaml"] },
455
+ version: versionFromCommands([{ command: "helm", args: ["version", "--short"] }]),
456
+ },
457
+ {
458
+ name: "julia",
459
+ symbol: "",
460
+ style: "bold purple",
461
+ priority: PRIORITY_DEFAULT,
462
+ detect: { extensions: ["jl"], files: ["Project.toml", "Manifest.toml"] },
463
+ version: versionFromCommands([{ command: "julia", args: ["--version"] }]),
464
+ },
465
+ {
466
+ name: "kotlin",
467
+ symbol: "",
468
+ style: "bold blue",
469
+ priority: PRIORITY_DEFAULT,
470
+ detect: { extensions: ["kt", "kts"] },
471
+ version: versionFromCommands([{ command: "kotlin", args: ["-version"] }]),
472
+ },
473
+ {
474
+ name: "meson",
475
+ symbol: "󰔷",
476
+ style: "blue bold",
477
+ priority: PRIORITY_DEFAULT,
478
+ detect: { env: (env) => env.MESON_DEVENV === "1" && Boolean(env.MESON_PROJECT_NAME?.trim()) },
479
+ version: noVersion,
480
+ },
481
+ {
482
+ name: "mojo",
483
+ symbol: "󰈸",
484
+ style: "bold 208",
485
+ priority: PRIORITY_DEFAULT,
486
+ detect: { extensions: ["mojo", "🔥"] },
487
+ version: versionFromCommands([{ command: "mojo", args: ["--version"] }]),
488
+ },
489
+ {
490
+ name: "nim",
491
+ symbol: "",
492
+ style: "bold yellow",
493
+ priority: PRIORITY_DEFAULT,
494
+ detect: { extensions: ["nim", "nims", "nimble"], files: ["nim.cfg"] },
495
+ version: versionFromCommands([{ command: "nim", args: ["--version"] }]),
496
+ },
497
+ {
498
+ name: "nix_shell",
499
+ symbol: "",
500
+ style: "bold blue",
501
+ priority: PRIORITY_DEFAULT,
502
+ detect: { env: (env) => env.IN_NIX_SHELL === "pure" || env.IN_NIX_SHELL === "impure" },
503
+ version: noVersion,
504
+ },
505
+ {
506
+ name: "ocaml",
507
+ symbol: "",
508
+ style: "bold yellow",
509
+ priority: PRIORITY_DEFAULT,
510
+ detect: {
511
+ extensions: ["opam", "ml", "mli", "re", "rei"],
512
+ files: ["dune", "dune-project", "jbuild", "jbuild-ignore", ".merlin"],
513
+ folders: ["_opam", "esy.lock"],
514
+ },
515
+ version: versionFromCommands([{ command: "ocaml", args: ["-version"] }]),
516
+ },
517
+ {
518
+ name: "odin",
519
+ symbol: "󰟢",
520
+ style: "bold bright-blue",
521
+ priority: PRIORITY_DEFAULT,
522
+ detect: { extensions: ["odin"] },
523
+ version: versionFromCommands([{ command: "odin", args: ["version"] }]),
524
+ },
525
+ {
526
+ name: "opa",
527
+ symbol: "",
528
+ style: "bold blue",
529
+ priority: PRIORITY_DEFAULT,
530
+ detect: { extensions: ["rego"] },
531
+ version: versionFromCommands([{ command: "opa", args: ["version"] }]),
532
+ },
533
+ {
534
+ name: "perl",
535
+ symbol: "",
536
+ style: "bold 149",
537
+ priority: PRIORITY_DEFAULT,
538
+ detect: {
539
+ extensions: ["pl", "pm", "pod"],
540
+ files: [
541
+ "Makefile.PL",
542
+ "Build.PL",
543
+ "cpanfile",
544
+ "cpanfile.snapshot",
545
+ "META.json",
546
+ "META.yml",
547
+ ".perl-version",
548
+ ],
549
+ },
550
+ version: versionFromCommands([{ command: "perl", args: ["--version"] }]),
551
+ },
552
+ {
553
+ name: "pixi",
554
+ symbol: "󰏗",
555
+ style: "yellow bold",
556
+ priority: PRIORITY_DEFAULT,
557
+ detect: {
558
+ files: ["pixi.toml", "pixi.lock"],
559
+ env: (env) => Boolean(env.PIXI_ENVIRONMENT_NAME?.trim()),
560
+ },
561
+ version: versionFromCommands([{ command: "pixi", args: ["--version"] }]),
562
+ },
563
+ {
564
+ name: "pulumi",
565
+ symbol: "",
566
+ style: "bold 5",
567
+ priority: PRIORITY_DEFAULT,
568
+ detect: { files: ["Pulumi.yaml", "Pulumi.yml"] },
569
+ version: versionFromCommands([{ command: "pulumi", args: ["version"] }]),
570
+ },
571
+ {
572
+ name: "purescript",
573
+ symbol: "",
574
+ style: "bold white",
575
+ priority: PRIORITY_DEFAULT,
576
+ detect: { extensions: ["purs"], files: ["spago.dhall", "spago.yaml", "spago.lock"] },
577
+ version: versionFromCommands([{ command: "purs", args: ["--version"] }]),
578
+ },
579
+ {
580
+ name: "raku",
581
+ symbol: "󱖊",
582
+ style: "bold 149",
583
+ priority: PRIORITY_DEFAULT,
584
+ detect: { extensions: ["p6", "pm6", "pod6", "raku", "rakumod"], files: ["META6.json"] },
585
+ version: versionFromCommands([{ command: "raku", args: ["--version"] }]),
586
+ },
587
+ {
588
+ name: "red",
589
+ symbol: "󱍼",
590
+ style: "red bold",
591
+ priority: PRIORITY_DEFAULT,
592
+ detect: { extensions: ["red", "reds"] },
593
+ version: versionFromCommands([{ command: "red", args: ["--version"] }]),
594
+ },
595
+ {
596
+ name: "rlang",
597
+ symbol: "󰟔",
598
+ style: "blue bold",
599
+ priority: PRIORITY_DEFAULT,
600
+ detect: {
601
+ extensions: ["R", "Rd", "Rmd", "Rproj", "Rsx"],
602
+ files: ["DESCRIPTION"],
603
+ folders: [".Rproj.user"],
604
+ },
605
+ version: versionFromCommands([{ command: "R", args: ["--version"] }]),
606
+ },
607
+ {
608
+ name: "scala",
609
+ symbol: "",
610
+ style: "red dimmed",
611
+ priority: PRIORITY_DEFAULT,
612
+ detect: {
613
+ extensions: ["sbt", "scala"],
614
+ files: [".scalaenv", ".sbtenv", "build.sbt"],
615
+ folders: [".metals"],
616
+ },
617
+ version: versionFromCommands([{ command: "scala", args: ["-version"] }]),
618
+ },
619
+ {
620
+ name: "solidity",
621
+ symbol: "",
622
+ style: "bold blue",
623
+ priority: PRIORITY_DEFAULT,
624
+ detect: { extensions: ["sol"] },
625
+ version: versionFromCommands([{ command: "solc", args: ["--version"] }]),
626
+ },
627
+ {
628
+ name: "spack",
629
+ symbol: "",
630
+ style: "bold blue",
631
+ priority: PRIORITY_DEFAULT,
632
+ detect: { env: (env) => Boolean(env.SPACK_ENV?.trim()) },
633
+ version: noVersion,
634
+ },
635
+ {
636
+ name: "swift",
637
+ symbol: "",
638
+ style: "bold 202",
639
+ priority: PRIORITY_DEFAULT,
640
+ detect: { extensions: ["swift"], files: ["Package.swift"] },
641
+ version: versionFromCommands([
642
+ { command: "swift", args: ["--version"], pattern: /Swift version\s+([0-9][^\s]*)/i },
643
+ ]),
644
+ },
645
+ {
646
+ name: "terraform",
647
+ symbol: "",
648
+ style: "bold 105",
649
+ priority: PRIORITY_DEFAULT,
650
+ detect: { extensions: ["tf", "tfplan", "tfstate"], folders: [".terraform"] },
651
+ version: versionFromCommands([
652
+ { command: "terraform", args: ["version"] },
653
+ { command: "tofu", args: ["version"] },
654
+ ]),
655
+ },
656
+ {
657
+ name: "typst",
658
+ symbol: "",
659
+ style: "bold #0093A7",
660
+ priority: PRIORITY_DEFAULT,
661
+ detect: { extensions: ["typ"], files: ["template.typ"] },
662
+ version: versionFromCommands([{ command: "typst", args: ["--version"] }]),
663
+ },
664
+ {
665
+ name: "vagrant",
666
+ symbol: "",
667
+ style: "cyan bold",
668
+ priority: PRIORITY_DEFAULT,
669
+ detect: { files: ["Vagrantfile"] },
670
+ version: versionFromCommands([{ command: "vagrant", args: ["--version"] }]),
671
+ },
672
+ {
673
+ name: "vlang",
674
+ symbol: "",
675
+ style: "blue bold",
676
+ priority: PRIORITY_DEFAULT,
677
+ detect: { extensions: ["v"], files: ["v.mod", "vpkg.json", ".vpkg-lock.json"] },
678
+ version: versionFromCommands([{ command: "v", args: ["version"] }]),
679
+ },
680
+ {
681
+ name: "zig",
682
+ symbol: "",
683
+ style: "bold yellow",
684
+ priority: PRIORITY_DEFAULT,
685
+ detect: { extensions: ["zig"], files: ["build.zig"] },
686
+ version: versionFromCommands([{ command: "zig", args: ["version"] }]),
687
+ },
688
+ ];
689
+
690
+ /** Runtimes sorted by priority — stable sort preserves definition order within the same priority. */
691
+ export const runtimeDefinitions: readonly RuntimeDef[] = [...runtimes].sort(
692
+ (a, b) => a.priority - b.priority,
693
+ );
694
+
695
+ export type { RuntimeDef };