@wolfstar/cli 0.2.0 → 0.4.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 (58) hide show
  1. package/README.md +53 -27
  2. package/dist/{build-B6xw00Ee.js → build-B1YfbqX3.js} +2 -2
  3. package/dist/{build-B6xw00Ee.js.map → build-B1YfbqX3.js.map} +1 -1
  4. package/dist/{build-CvSvbsYN.js → build-vpcF5bwc.js} +5 -4
  5. package/dist/build-vpcF5bwc.js.map +1 -0
  6. package/dist/cli.js +6 -6
  7. package/dist/{codegen-mYkL-GBf.js → codegen-1kW_OnrL.js} +2 -2
  8. package/dist/{codegen-mYkL-GBf.js.map → codegen-1kW_OnrL.js.map} +1 -1
  9. package/dist/{codegen-DjPOn7cp.js → codegen-DHQH83M3.js} +2 -2
  10. package/dist/{codegen-DjPOn7cp.js.map → codegen-DHQH83M3.js.map} +1 -1
  11. package/dist/{commands-Dw2LFWV-.js → commands-DPGDL7ft.js} +4 -4
  12. package/dist/commands-DPGDL7ft.js.map +1 -0
  13. package/dist/{commands-BkGKs_Bg.js → commands-hpnmaBM2.js} +4 -4
  14. package/dist/{commands-BkGKs_Bg.js.map → commands-hpnmaBM2.js.map} +1 -1
  15. package/dist/{dev-CWA_JVTb.js → dev-Dh1Euxk1.js} +111 -68
  16. package/dist/dev-Dh1Euxk1.js.map +1 -0
  17. package/dist/{dev-BCgaVd0m.js → dev-hT1WR1Kh.js} +2 -2
  18. package/dist/{dev-BCgaVd0m.js.map → dev-hT1WR1Kh.js.map} +1 -1
  19. package/dist/external-Bk4EESdT.js.map +1 -1
  20. package/dist/index.d.ts +14 -10
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/{info-Czh4LUsD.js → info-BrxKCcUW.js} +2 -2
  24. package/dist/{info-Czh4LUsD.js.map → info-BrxKCcUW.js.map} +1 -1
  25. package/dist/{info-BqxpktLG.js → info-rYRLITnv.js} +2 -2
  26. package/dist/{info-BqxpktLG.js.map → info-rYRLITnv.js.map} +1 -1
  27. package/dist/locales-B3mRenhY.js +104 -0
  28. package/dist/locales-B3mRenhY.js.map +1 -0
  29. package/dist/log-buffer-D-nj2ZEU.js +72 -0
  30. package/dist/log-buffer-D-nj2ZEU.js.map +1 -0
  31. package/dist/none-DEo7zEr9.js.map +1 -1
  32. package/dist/{output-mode-ChrOf0LO.js → output-mode-Cxes6YUW.js} +4 -2
  33. package/dist/output-mode-Cxes6YUW.js.map +1 -0
  34. package/dist/{prepare-BXcm2Ukp.js → prepare-90XQCoak.js} +1 -1
  35. package/dist/{prepare-D5NZ0w4t.js → prepare-CHLrneYU.js} +2 -2
  36. package/dist/{prepare-D5NZ0w4t.js.map → prepare-CHLrneYU.js.map} +1 -1
  37. package/dist/{prepare-CVf88_Or.js → prepare-hOwjyelr.js} +2 -2
  38. package/dist/{prepare-CVf88_Or.js.map → prepare-hOwjyelr.js.map} +1 -1
  39. package/dist/process-supervisor-CJOdmp0W.js.map +1 -1
  40. package/dist/tsc-BqZfDTD0.js.map +1 -1
  41. package/dist/{tsdown-BEFq2API.js → tsdown-DN3PQTJf.js} +30 -13
  42. package/dist/tsdown-DN3PQTJf.js.map +1 -0
  43. package/dist/tui-BCGQrMQo.js +947 -0
  44. package/dist/tui-BCGQrMQo.js.map +1 -0
  45. package/dist/{tunnel-B8Id4-lR.js → tunnel-mGJe2zuE.js} +20 -7
  46. package/dist/tunnel-mGJe2zuE.js.map +1 -0
  47. package/dist/vite-27ZbreDz.js.map +1 -1
  48. package/package.json +10 -9
  49. package/dist/build-CvSvbsYN.js.map +0 -1
  50. package/dist/builders-D97Uqjwg.js +0 -44
  51. package/dist/builders-D97Uqjwg.js.map +0 -1
  52. package/dist/commands-Dw2LFWV-.js.map +0 -1
  53. package/dist/dev-CWA_JVTb.js.map +0 -1
  54. package/dist/output-mode-ChrOf0LO.js.map +0 -1
  55. package/dist/tsdown-BEFq2API.js.map +0 -1
  56. package/dist/tui-BTRFsLQR.js +0 -770
  57. package/dist/tui-BTRFsLQR.js.map +0 -1
  58. package/dist/tunnel-B8Id4-lR.js.map +0 -1
@@ -1,69 +1,20 @@
1
1
  import { n as ExitCode, t as CliError } from "./errors-Bket6XFn.js";
2
- import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode } from "./output-mode-ChrOf0LO.js";
2
+ import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode } from "./output-mode-Cxes6YUW.js";
3
3
  import { n as resolveCwd } from "./args-Ch1KXUMn.js";
4
4
  import { n as createLineSplitter, t as ProcessSupervisor } from "./process-supervisor-CJOdmp0W.js";
5
5
  import { r as resolveBinary } from "./project-DHF3qdm-.js";
6
6
  import { n as resolveTscBinary } from "./tsc-BqZfDTD0.js";
7
- import { n as createBuilder, t as assertSupportedExperiments } from "./builders-D97Uqjwg.js";
8
- import { t as prepareAutoImports } from "./prepare-D5NZ0w4t.js";
9
- import { t as Tunnel } from "./tunnel-B8Id4-lR.js";
10
- import { loadStarsConfig } from "@wolfstar/http-framework/config";
7
+ import { n as assertSupportedExperiments, r as createBuilder, t as Locales } from "./locales-B3mRenhY.js";
8
+ import { t as prepareAutoImports } from "./prepare-CHLrneYU.js";
9
+ import { t as Tunnel } from "./tunnel-mGJe2zuE.js";
10
+ import { n as classifyAppLine, t as LogBuffer } from "./log-buffer-D-nj2ZEU.js";
11
+ import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
11
12
  import { createWriteStream, mkdirSync } from "node:fs";
12
13
  import { dirname } from "node:path";
13
14
  import { EventEmitter } from "node:events";
14
15
  import { spawn } from "node:child_process";
15
16
  import { lookup } from "node:dns/promises";
16
17
 
17
- //#region src/lib/log-buffer.ts
18
- /**
19
- * A bounded, in-memory log store shared by the dev service and its renderers.
20
- */
21
- var LogBuffer = class extends EventEmitter {
22
- capacity;
23
- #entries = [];
24
- #nextId = 1;
25
- constructor(capacity = 2e3) {
26
- super();
27
- this.capacity = capacity;
28
- }
29
- push(input) {
30
- const entry = {
31
- id: this.#nextId++,
32
- time: Date.now(),
33
- ...input
34
- };
35
- this.#entries.push(entry);
36
- if (this.#entries.length > this.capacity) this.#entries.splice(0, this.#entries.length - this.capacity);
37
- this.emit("entry", entry);
38
- return entry;
39
- }
40
- entries() {
41
- return this.#entries;
42
- }
43
- filter(filter) {
44
- const query = filter.query?.toLowerCase() ?? null;
45
- return this.#entries.filter((entry) => (!filter.source || entry.source === filter.source) && (!filter.level || matchesLevel(entry.level, filter.level)) && (!query || entry.text.toLowerCase().includes(query)));
46
- }
47
- clear() {
48
- this.#entries = [];
49
- this.emit("clear");
50
- }
51
- };
52
- const LEVEL_ORDER = {
53
- debug: 0,
54
- info: 1,
55
- success: 1,
56
- warn: 2,
57
- error: 3
58
- };
59
- /**
60
- * Whether `level` is at least as severe as `minimum`.
61
- */
62
- function matchesLevel(level, minimum) {
63
- return LEVEL_ORDER[level] >= LEVEL_ORDER[minimum];
64
- }
65
-
66
- //#endregion
67
18
  //#region src/lib/typechecker.ts
68
19
  const WATCH_START = /Starting (incremental )?compilation/;
69
20
  const WATCH_DONE = /Found (\d+) errors?\. Watching for file changes/;
@@ -277,6 +228,7 @@ var DevService = class extends EventEmitter {
277
228
  supervisor;
278
229
  typechecker;
279
230
  tunnel;
231
+ locales;
280
232
  #build = "idle";
281
233
  #health = "unknown";
282
234
  #restarts = 0;
@@ -288,6 +240,12 @@ var DevService = class extends EventEmitter {
288
240
  #pendingReason = null;
289
241
  #stopped = false;
290
242
  #queue = Promise.resolve();
243
+ #progress = {
244
+ fraction: 0,
245
+ message: "preparing your app",
246
+ startedAt: Date.now(),
247
+ readyMs: null
248
+ };
291
249
  constructor(config, options) {
292
250
  super();
293
251
  this.config = config;
@@ -296,19 +254,46 @@ var DevService = class extends EventEmitter {
296
254
  this.supervisor = options.supervisor ?? createSupervisor(config);
297
255
  this.typechecker = options.typechecker ?? new Typechecker(config);
298
256
  this.tunnel = options.tunnel ?? new Tunnel(config);
299
- this.builder.on("start", () => this.#setBuild("building"));
257
+ this.locales = new Locales(config);
258
+ this.builder.on("start", () => {
259
+ this.#progress = {
260
+ fraction: 0,
261
+ message: "preparing build",
262
+ startedAt: Date.now(),
263
+ readyMs: null
264
+ };
265
+ this.#setBuild("building");
266
+ });
267
+ this.builder.on("progress", (fraction, message) => {
268
+ this.#progress = {
269
+ ...this.#progress,
270
+ fraction: Math.max(this.#progress.fraction, Math.min(.75, fraction)),
271
+ message
272
+ };
273
+ this.#emitStatus();
274
+ });
300
275
  this.builder.on("success", (outcome) => this.#onBuildSuccess(outcome));
301
276
  this.builder.on("failure", (outcome) => this.#onBuildFailure(outcome));
302
277
  this.builder.on("log", (level, text) => this.log("build", level, text));
303
- this.supervisor.on("state", () => this.#emitStatus());
304
- this.supervisor.on("stdout", (line) => this.log("app", "info", line));
305
- this.supervisor.on("stderr", (line) => this.log("app", "error", line));
278
+ this.supervisor.on("state", () => {
279
+ if (this.supervisor.state === "running") {
280
+ this.#settleProgress();
281
+ this.#checkHealth();
282
+ }
283
+ this.#emitStatus();
284
+ });
285
+ this.supervisor.on("stdout", (line) => this.log("app", classifyAppLine(line, "info"), line));
286
+ this.supervisor.on("stderr", (line) => this.log("app", classifyAppLine(line, "error"), line));
306
287
  this.supervisor.on("error", (error) => this.log("stars", "error", `Failed to start the bot: ${error.message}`));
307
288
  this.supervisor.on("exit", (exit) => this.#onExit(exit));
308
289
  this.typechecker.on("log", (level, text) => this.log("tsc", level, text));
309
290
  this.typechecker.on("state", () => this.#emitStatus());
310
291
  this.tunnel.on("log", (level, text) => this.log("tunnel", level, text));
311
292
  this.tunnel.on("state", () => this.#emitStatus());
293
+ this.locales.on("log", (level, text) => this.log("build", level, text));
294
+ this.locales.on("change", () => {
295
+ if (this.#build === "ok") this.#scheduleRestart("build");
296
+ });
312
297
  if (config.dev.url && config.dev.health) {
313
298
  const interval = options.healthInterval ?? 5e3;
314
299
  this.#healthTimer = setInterval(() => void this.#checkHealth(), interval);
@@ -317,6 +302,7 @@ var DevService = class extends EventEmitter {
317
302
  }
318
303
  get status() {
319
304
  return {
305
+ progress: this.#progress,
320
306
  process: this.supervisor.state,
321
307
  build: this.#build,
322
308
  health: this.#health,
@@ -345,8 +331,10 @@ var DevService = class extends EventEmitter {
345
331
  */
346
332
  async start() {
347
333
  this.#stopped = false;
348
- this.log("stars", "info", `Watching ${this.config.build.tool === "none" ? "sources" : `with ${this.config.build.tool}`}, entry ${this.config.entry}`);
334
+ const entry = displayPath(this.config.root, this.config.entry);
335
+ this.log("stars", "info", this.config.build.tool === "none" ? `Watching ${entry}` : `Watching ${entry} with ${this.config.build.tool}`);
349
336
  if (this.config.dev.typecheck.enabled) this.typechecker.start();
337
+ await this.locales.watch();
350
338
  this.tunnel.start();
351
339
  await this.builder.watch();
352
340
  }
@@ -357,6 +345,12 @@ var DevService = class extends EventEmitter {
357
345
  this.#clearRestartTimer();
358
346
  return this.#enqueue(async () => {
359
347
  if (this.#stopped) return;
348
+ if (reason === "manual" || reason === "crash") this.#progress = {
349
+ fraction: 0,
350
+ message: "restarting the bot",
351
+ startedAt: Date.now(),
352
+ readyMs: null
353
+ };
360
354
  this.#lastRestartReason = reason;
361
355
  if (this.supervisor.running) {
362
356
  this.#restarts++;
@@ -364,11 +358,20 @@ var DevService = class extends EventEmitter {
364
358
  await this.supervisor.stop();
365
359
  } else this.log("stars", "info", `Starting (${describeReason(reason)})`);
366
360
  if (this.#stopped) return;
367
- this.supervisor.start();
361
+ this.#progress = {
362
+ ...this.#progress,
363
+ fraction: .75,
364
+ message: "starting the bot"
365
+ };
368
366
  this.#health = "unknown";
367
+ this.supervisor.start();
369
368
  this.#emitStatus();
370
369
  });
371
370
  }
371
+ /** Opens or closes the public tunnel (used by the `t` key). */
372
+ toggleTunnel() {
373
+ return this.tunnel.toggle();
374
+ }
372
375
  /**
373
376
  * Stops the watcher and the bot. Safe to call more than once.
374
377
  */
@@ -382,7 +385,8 @@ var DevService = class extends EventEmitter {
382
385
  this.builder.close(),
383
386
  this.supervisor.stop(),
384
387
  this.typechecker.close(),
385
- this.tunnel.close()
388
+ this.tunnel.close(),
389
+ this.locales.close()
386
390
  ]);
387
391
  });
388
392
  }
@@ -390,7 +394,22 @@ var DevService = class extends EventEmitter {
390
394
  this.logs.clear();
391
395
  }
392
396
  #onBuildSuccess(outcome) {
397
+ try {
398
+ this.locales.copy();
399
+ } catch (error) {
400
+ this.#onBuildFailure({
401
+ ...outcome,
402
+ ok: false,
403
+ message: `Failed to copy locales: ${error instanceof Error ? error.message : String(error)}`
404
+ });
405
+ return;
406
+ }
393
407
  this.#lastBuild = outcome;
408
+ this.#progress = {
409
+ ...this.#progress,
410
+ fraction: .75,
411
+ message: "starting the bot"
412
+ };
394
413
  this.#setBuild("ok");
395
414
  if (this.#stopped) return;
396
415
  this.typechecker.check();
@@ -437,17 +456,30 @@ var DevService = class extends EventEmitter {
437
456
  }
438
457
  async #checkHealth() {
439
458
  if (!this.supervisor.running || !this.config.dev.url || !this.config.dev.health) return;
459
+ const pid = this.supervisor.pid;
440
460
  let next;
441
461
  try {
442
462
  next = (await fetch(new URL(this.config.dev.health, this.config.dev.url), { signal: AbortSignal.timeout(2e3) })).status < 500 ? "ok" : "down";
443
463
  } catch {
444
464
  next = "down";
445
465
  }
466
+ if (this.#stopped || pid !== this.supervisor.pid) return;
446
467
  if (next !== this.#health) {
447
468
  this.#health = next;
469
+ if (next === "ok") this.#settleProgress();
448
470
  this.#emitStatus();
449
471
  }
450
472
  }
473
+ #settleProgress() {
474
+ if (this.config.dev.health && this.#health !== "ok") return;
475
+ if (this.#build !== "ok") return;
476
+ this.#progress = {
477
+ ...this.#progress,
478
+ fraction: 1,
479
+ message: "watching for changes",
480
+ readyMs: this.#progress.readyMs ?? Date.now() - this.#progress.startedAt
481
+ };
482
+ }
451
483
  #emitStatus() {
452
484
  this.emit("status", this.status);
453
485
  }
@@ -465,7 +497,8 @@ function createSupervisor(config) {
465
497
  ...process.env,
466
498
  ...config.dev.env,
467
499
  STARS_DEV: "1",
468
- FORCE_COLOR: process.env.FORCE_COLOR ?? (process.stdout.isTTY ? "1" : void 0)
500
+ NODE_ENV: "development",
501
+ FORCE_COLOR: process.env.NO_COLOR !== void 0 ? void 0 : process.env.FORCE_COLOR ?? (process.stdout.isTTY ? "1" : void 0)
469
502
  },
470
503
  killTimeout: config.dev.killTimeout
471
504
  });
@@ -549,18 +582,22 @@ function format(entry) {
549
582
  //#endregion
550
583
  //#region src/lib/tasks/dev.ts
551
584
  async function runDev(options) {
585
+ process.env.NODE_ENV = "development";
552
586
  const config = await resolveDevConfig(await loadStarsConfig({
553
587
  cwd: resolveCwd(options),
554
- configFile: options.config
588
+ configFile: options.config,
589
+ env: {
590
+ ...process.env,
591
+ NODE_ENV: "development"
592
+ }
555
593
  }));
556
594
  assertSupportedExperiments(config);
557
- await prepareAutoImports(config);
558
595
  const mode = resolveOutputMode({ tui: options.tui });
559
596
  const color = shouldUseColor();
560
597
  const service = new DevService(config, { builder: await createBuilder(config) });
561
598
  const logFile = config.dev.logFile ? new LogFileWriter(config.dev.logFile, service.logs) : null;
562
599
  logFile?.open();
563
- const renderer = mode === "tui" ? (await import("./tui-BTRFsLQR.js")).createTuiRenderer(service, {
600
+ const renderer = mode === "tui" ? (await import("./tui-BCGQrMQo.js")).createTuiRenderer(service, {
564
601
  color,
565
602
  reducedMotion: prefersReducedMotion()
566
603
  }) : (await import("./plain-CEe4X_Cz.js")).createPlainRenderer(service, { color });
@@ -579,7 +616,13 @@ async function runDev(options) {
579
616
  process.once("SIGHUP", () => void shutdown(ExitCode.Terminated));
580
617
  if (process.platform !== "win32") process.on("SIGUSR2", () => void service.restart("manual"));
581
618
  const finished = renderer.start().then(() => shutdown(ExitCode.Ok));
582
- await service.start();
619
+ try {
620
+ await prepareAutoImports(config);
621
+ await service.start();
622
+ } catch (error) {
623
+ service.log("stars", "error", error instanceof Error ? error.stack ?? error.message : String(error));
624
+ await shutdown(ExitCode.Error);
625
+ }
583
626
  await finished;
584
627
  }
585
628
  /**
@@ -601,4 +644,4 @@ async function resolveDevConfig(config) {
601
644
 
602
645
  //#endregion
603
646
  export { runDev };
604
- //# sourceMappingURL=dev-CWA_JVTb.js.map
647
+ //# sourceMappingURL=dev-Dh1Euxk1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-Dh1Euxk1.js","names":[],"sources":["../src/lib/typechecker.ts","../src/lib/dev-service.ts","../src/lib/host.ts","../src/lib/log-file.ts","../src/lib/tasks/dev.ts"],"sourcesContent":["import type { ResolvedStarsConfig, StarsTypechecker } from '@wolfstar/http-framework/config';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\nimport { resolveTscBinary } from './builders/tsc.js';\nimport { CliError } from './errors.js';\nimport type { LogLevel } from './log-buffer.js';\nimport { createLineSplitter } from './process-supervisor.js';\nimport { resolveBinary } from './project.js';\n\nconst WATCH_START = /Starting (incremental )?compilation/;\nconst WATCH_DONE = /Found (\\d+) errors?\\. Watching for file changes/;\nconst ONE_SHOT_DONE = /Found (\\d+) errors?/;\nconst ERROR_LINE = /error TS\\d+:/;\n\nexport type TypecheckState = 'idle' | 'checking' | 'ok' | 'failed';\n\nexport interface TypecheckerEvents {\n\tlog: [level: LogLevel, text: string];\n\tstate: [state: TypecheckState, errors: number];\n}\n\nexport interface TypecheckCommand {\n\t/** The executable, and whether it is a script `node` has to run. */\n\treadonly command: string;\n\treadonly args: readonly string[];\n\treadonly node: boolean;\n\t/** Whether the checker watches the project itself, or has to be re-run after every build. */\n\treadonly watch: boolean;\n}\n\n/**\n * Runs a type checker next to the bot and reports type errors on their own channel, without ever blocking builds or\n * restarts: `stars dev` keeps running whatever the build tool produced, the way Seedcord's `hmr.typecheck` and\n * Vite's `checker` plugin do.\n *\n * `tsc` and `golar` (which forwards to TypeScript) watch the project themselves; `tsz` has no watch mode, so\n * {@link Typechecker.check} re-runs it after every build instead.\n */\nexport class Typechecker extends EventEmitter<TypecheckerEvents> {\n\t#child: ChildProcess | null = null;\n\t#state: TypecheckState = 'idle';\n\t#errors = 0;\n\t#pending = false;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t}\n\n\tpublic get state(): TypecheckState {\n\t\treturn this.#state;\n\t}\n\n\tpublic get errors(): number {\n\t\treturn this.#errors;\n\t}\n\n\t/** Whether the checker re-runs per build instead of watching on its own. */\n\tpublic get oneShot(): boolean {\n\t\treturn this.config.dev.typecheck.enabled && !resolveTypecheckCommand(this.config).watch;\n\t}\n\n\tpublic start(): void {\n\t\tif (!this.config.dev.typecheck.enabled) return;\n\t\tthis.#run();\n\t}\n\n\t/**\n\t * Re-runs a checker that cannot watch. Called after every successful build; a run already in flight is replaced,\n\t * so a fast series of builds only leaves the last check standing.\n\t */\n\tpublic check(): void {\n\t\tif (!this.oneShot) return;\n\t\tif (this.#child) {\n\t\t\tthis.#pending = true;\n\t\t\tthis.#child.kill();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#run();\n\t}\n\n\tpublic close(): Promise<void> {\n\t\tconst child = this.#child;\n\t\tthis.#child = null;\n\t\tthis.#pending = false;\n\t\tif (!child || child.exitCode !== null) return Promise.resolve();\n\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once('exit', () => resolve());\n\t\t\tchild.kill();\n\t\t});\n\t}\n\n\t#run(): void {\n\t\tconst { command, args, node, watch } = resolveTypecheckCommand(this.config);\n\t\tconst child = spawn(node ? process.execPath : command, node ? [command, ...args] : [...args], {\n\t\t\tcwd: this.config.root,\n\t\t\tenv: process.env,\n\t\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\t\twindowsHide: true\n\t\t});\n\t\tthis.#child = child;\n\t\tthis.#setState('checking', 0);\n\n\t\tlet errors = 0;\n\t\tconst handleLine = (line: string) => {\n\t\t\tif (ERROR_LINE.test(line)) errors++;\n\t\t\tthis.#handleLine(line);\n\t\t};\n\n\t\tconst stdout = createLineSplitter(handleLine);\n\t\tconst stderr = createLineSplitter(handleLine);\n\t\tchild.stdout?.on('data', stdout.push);\n\t\tchild.stderr?.on('data', stderr.push);\n\n\t\tchild.once('exit', (code) => {\n\t\t\tstdout.flush();\n\t\t\tstderr.flush();\n\t\t\tthis.#child = null;\n\n\t\t\tif (!watch && this.#state === 'checking') {\n\t\t\t\t// A one-shot checker only reports through its exit code when it prints no summary line.\n\t\t\t\tthis.#setState(code === 0 && errors === 0 ? 'ok' : 'failed', errors);\n\t\t\t}\n\n\t\t\tif (this.#pending) {\n\t\t\t\tthis.#pending = false;\n\t\t\t\tthis.#run();\n\t\t\t}\n\t\t});\n\t\tchild.once('error', (error: NodeJS.ErrnoException) => {\n\t\t\tthis.#child = null;\n\t\t\tthis.emit('log', 'error', error.code === 'ENOENT' ? `${command} is not installed` : error.message);\n\t\t\tthis.#setState('failed', this.#errors);\n\t\t});\n\t}\n\n\t#handleLine(line: string): void {\n\t\tconst text = line.trim();\n\t\tif (text.length === 0) return;\n\n\t\tif (WATCH_START.test(text)) {\n\t\t\tthis.#setState('checking', 0);\n\t\t\treturn;\n\t\t}\n\n\t\tif (ERROR_LINE.test(text)) {\n\t\t\tthis.emit('log', 'error', text);\n\t\t\treturn;\n\t\t}\n\n\t\tconst done = WATCH_DONE.exec(text) ?? ONE_SHOT_DONE.exec(text);\n\t\tif (done) {\n\t\t\tconst errors = Number(done[1]);\n\t\t\tthis.#setState(errors === 0 ? 'ok' : 'failed', errors);\n\t\t\tthis.emit('log', errors === 0 ? 'success' : 'error', errors === 0 ? 'No type errors' : `${errors} type error${errors === 1 ? '' : 's'}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.emit('log', 'info', text);\n\t}\n\n\t#setState(state: TypecheckState, errors: number): void {\n\t\tthis.#state = state;\n\t\tthis.#errors = errors;\n\t\tthis.emit('state', state, errors);\n\t}\n}\n\n/**\n * Builds the command line of the configured type checker, resolved from the project's own `node_modules`.\n *\n * @throws {CliError} when the checker is not installed in the project.\n */\nexport function resolveTypecheckCommand(config: ResolvedStarsConfig): TypecheckCommand {\n\tconst { checker, tsconfig } = config.dev.typecheck;\n\tconst project = tsconfig!;\n\n\tswitch (checker) {\n\t\tcase 'golar': {\n\t\t\t// `golar tsc` forwards everything after it to the TypeScript CLI, watch mode included.\n\t\t\tconst golar = resolveBinary(config.root, 'golar', 'golar');\n\t\t\tif (!golar) throw missing(config, 'golar', 'Install it with `pnpm add -D golar`');\n\n\t\t\treturn { command: golar, args: ['tsc', ...WATCH_ARGS, '-p', project], node: true, watch: true };\n\t\t}\n\n\t\tcase 'tsz': {\n\t\t\t// `tsz` is an early, tsc-compatible checker with no watch mode; `try-tsz` is its comparison harness.\n\t\t\tconst tsz = resolveBinary(config.root, '@mohsen-azimi/tsz-dev', 'tsz');\n\t\t\tif (tsz) return { command: tsz, args: ['--noEmit', '-p', project], node: true, watch: false };\n\n\t\t\tconst tryTsz = resolveBinary(config.root, 'try-tsz', 'try-tsz');\n\t\t\tif (tryTsz) return { command: tryTsz, args: ['-p', project], node: true, watch: false };\n\n\t\t\tthrow missing(config, 'tsz', 'Install it with `pnpm add -D @mohsen-azimi/tsz-dev` (or `try-tsz`)');\n\t\t}\n\n\t\tdefault: {\n\t\t\tconst tsc = resolveTscBinary(config.root);\n\t\t\tif (!tsc) throw missing(config, 'typescript', 'Install it with `pnpm add -D typescript`');\n\n\t\t\treturn { command: tsc, args: [...WATCH_ARGS, '-p', project], node: true, watch: true };\n\t\t}\n\t}\n}\n\nconst WATCH_ARGS = ['--noEmit', '--watch', '--preserveWatchOutput', '--pretty', 'false'] as const;\n\nfunction missing(config: ResolvedStarsConfig, name: string, install: string): CliError {\n\treturn new CliError(`\"${name}\" is not installed in ${config.root}`, {\n\t\tcode: 'DEPENDENCY_MISSING',\n\t\thint: `${install}, pick another \\`dev.typecheck.checker\\`, or set \\`dev.typecheck\\` to false.`\n\t});\n}\n\nexport type { StarsTypechecker };\n","import { EventEmitter } from 'node:events';\nimport type { Builder, BuildOutcome } from './builders/types.js';\nimport { displayPath, type ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { classifyAppLine, LogBuffer, type LogLevel, type LogSource } from './log-buffer.js';\nimport { Locales } from './locales.js';\nimport { ProcessSupervisor, type ProcessExit, type ProcessState } from './process-supervisor.js';\nimport { Tunnel, type TunnelState } from './tunnel.js';\nimport { Typechecker, type TypecheckState } from './typechecker.js';\n\nexport type BuildState = 'idle' | 'building' | 'ok' | 'failed';\nexport type HealthState = 'unknown' | 'ok' | 'down';\nexport type RestartReason = 'initial' | 'build' | 'manual' | 'crash';\n\nexport interface DevStatus {\n\treadonly progress: { readonly fraction: number; readonly message: string; readonly startedAt: number; readonly readyMs: number | null };\n\treadonly process: ProcessState;\n\treadonly build: BuildState;\n\treadonly health: HealthState;\n\treadonly pid: number | null;\n\treadonly startedAt: number | null;\n\treadonly restarts: number;\n\treadonly lastRestartReason: RestartReason | null;\n\treadonly lastBuild: BuildOutcome | null;\n\treadonly lastExit: ProcessExit | null;\n\treadonly url: string | null;\n\treadonly typecheck: TypecheckState;\n\treadonly typeErrors: number;\n\treadonly tunnel: TunnelState;\n\treadonly tunnelUrl: string | null;\n}\n\nexport interface DevServiceEvents {\n\tstatus: [status: DevStatus];\n}\n\nexport interface DevServiceOptions {\n\tbuilder: Builder;\n\tlogs?: LogBuffer;\n\t/** Overrides for tests. */\n\tsupervisor?: ProcessSupervisor;\n\ttypechecker?: Typechecker;\n\ttunnel?: Tunnel;\n\thealthInterval?: number;\n}\n\n/**\n * The headless heart of `stars dev`: builds, (re)starts the bot and exposes state and logs.\n * Renderers (plain or TUI) only subscribe to it, they never own behaviour.\n */\nexport class DevService extends EventEmitter<DevServiceEvents> {\n\tpublic readonly logs: LogBuffer;\n\tpublic readonly builder: Builder;\n\tpublic readonly supervisor: ProcessSupervisor;\n\tpublic readonly typechecker: Typechecker;\n\tpublic readonly tunnel: Tunnel;\n\tpublic readonly locales: Locales;\n\n\t#build: BuildState = 'idle';\n\t#health: HealthState = 'unknown';\n\t#restarts = 0;\n\t#lastRestartReason: RestartReason | null = null;\n\t#lastBuild: BuildOutcome | null = null;\n\t#lastExit: ProcessExit | null = null;\n\t#restartTimer: NodeJS.Timeout | null = null;\n\t#healthTimer: NodeJS.Timeout | null = null;\n\t#pendingReason: RestartReason | null = null;\n\t#stopped = false;\n\t#queue: Promise<void> = Promise.resolve();\n\t#progress = { fraction: 0, message: 'preparing your app', startedAt: Date.now(), readyMs: null as number | null };\n\n\tpublic constructor(\n\t\tpublic readonly config: ResolvedStarsConfig,\n\t\toptions: DevServiceOptions\n\t) {\n\t\tsuper();\n\t\tthis.logs = options.logs ?? new LogBuffer();\n\t\tthis.builder = options.builder;\n\t\tthis.supervisor = options.supervisor ?? createSupervisor(config);\n\t\tthis.typechecker = options.typechecker ?? new Typechecker(config);\n\t\tthis.tunnel = options.tunnel ?? new Tunnel(config);\n\t\tthis.locales = new Locales(config);\n\n\t\tthis.builder.on('start', () => {\n\t\t\tthis.#progress = { fraction: 0, message: 'preparing build', startedAt: Date.now(), readyMs: null };\n\t\t\tthis.#setBuild('building');\n\t\t});\n\t\tthis.builder.on('progress', (fraction, message) => {\n\t\t\tthis.#progress = { ...this.#progress, fraction: Math.max(this.#progress.fraction, Math.min(0.75, fraction)), message };\n\t\t\tthis.#emitStatus();\n\t\t});\n\t\tthis.builder.on('success', (outcome) => this.#onBuildSuccess(outcome));\n\t\tthis.builder.on('failure', (outcome) => this.#onBuildFailure(outcome));\n\t\tthis.builder.on('log', (level, text) => this.log('build', level, text));\n\n\t\tthis.supervisor.on('state', () => {\n\t\t\tif (this.supervisor.state === 'running') {\n\t\t\t\tthis.#settleProgress();\n\t\t\t\tvoid this.#checkHealth();\n\t\t\t}\n\t\t\tthis.#emitStatus();\n\t\t});\n\t\tthis.supervisor.on('stdout', (line) => this.log('app', classifyAppLine(line, 'info'), line));\n\t\tthis.supervisor.on('stderr', (line) => this.log('app', classifyAppLine(line, 'error'), line));\n\t\tthis.supervisor.on('error', (error) => this.log('stars', 'error', `Failed to start the bot: ${error.message}`));\n\t\tthis.supervisor.on('exit', (exit) => this.#onExit(exit));\n\n\t\tthis.typechecker.on('log', (level, text) => this.log('tsc', level, text));\n\t\tthis.typechecker.on('state', () => this.#emitStatus());\n\t\tthis.tunnel.on('log', (level, text) => this.log('tunnel', level, text));\n\t\tthis.tunnel.on('state', () => this.#emitStatus());\n\t\tthis.locales.on('log', (level, text) => this.log('build', level, text));\n\t\tthis.locales.on('change', () => {\n\t\t\tif (this.#build === 'ok') this.#scheduleRestart('build');\n\t\t});\n\n\t\tif (config.dev.url && config.dev.health) {\n\t\t\tconst interval = options.healthInterval ?? 5000;\n\t\t\tthis.#healthTimer = setInterval(() => void this.#checkHealth(), interval);\n\t\t\tthis.#healthTimer.unref();\n\t\t}\n\t}\n\n\tpublic get status(): DevStatus {\n\t\treturn {\n\t\t\tprogress: this.#progress,\n\t\t\tprocess: this.supervisor.state,\n\t\t\tbuild: this.#build,\n\t\t\thealth: this.#health,\n\t\t\tpid: this.supervisor.pid,\n\t\t\tstartedAt: this.supervisor.startedAt,\n\t\t\trestarts: this.#restarts,\n\t\t\tlastRestartReason: this.#lastRestartReason,\n\t\t\tlastBuild: this.#lastBuild,\n\t\t\tlastExit: this.#lastExit,\n\t\t\turl: this.config.dev.url,\n\t\t\ttypecheck: this.typechecker.state,\n\t\t\ttypeErrors: this.typechecker.errors,\n\t\t\ttunnel: this.tunnel.state,\n\t\t\ttunnelUrl: this.tunnel.url\n\t\t};\n\t}\n\n\tpublic log(source: LogSource, level: LogLevel, text: string): void {\n\t\tthis.logs.push({ source, level, text });\n\t}\n\n\t/**\n\t * Starts watching; the bot starts after the first successful build.\n\t */\n\tpublic async start(): Promise<void> {\n\t\tthis.#stopped = false;\n\t\tconst entry = displayPath(this.config.root, this.config.entry);\n\t\tthis.log('stars', 'info', this.config.build.tool === 'none' ? `Watching ${entry}` : `Watching ${entry} with ${this.config.build.tool}`);\n\t\tif (this.config.dev.typecheck.enabled) this.typechecker.start();\n\t\tawait this.locales.watch();\n\t\t// The tunnel comes up next to the build: neither waits for the other, and a failed tunnel never stops the bot.\n\t\tvoid this.tunnel.start();\n\t\tawait this.builder.watch();\n\t}\n\n\t/**\n\t * Restarts the bot immediately (used by the `r` key and by `SIGUSR2`).\n\t */\n\tpublic restart(reason: RestartReason = 'manual'): Promise<void> {\n\t\tthis.#clearRestartTimer();\n\t\treturn this.#enqueue(async () => {\n\t\t\tif (this.#stopped) return;\n\t\t\tif (reason === 'manual' || reason === 'crash') {\n\t\t\t\tthis.#progress = { fraction: 0, message: 'restarting the bot', startedAt: Date.now(), readyMs: null };\n\t\t\t}\n\t\t\tthis.#lastRestartReason = reason;\n\t\t\tif (this.supervisor.running) {\n\t\t\t\tthis.#restarts++;\n\t\t\t\tthis.log('stars', 'info', `Restarting (${describeReason(reason)})`);\n\t\t\t\tawait this.supervisor.stop();\n\t\t\t} else {\n\t\t\t\tthis.log('stars', 'info', `Starting (${describeReason(reason)})`);\n\t\t\t}\n\n\t\t\tif (this.#stopped) return;\n\t\t\tthis.#progress = { ...this.#progress, fraction: 0.75, message: 'starting the bot' };\n\t\t\tthis.#health = 'unknown';\n\t\t\tthis.supervisor.start();\n\t\t\tthis.#emitStatus();\n\t\t});\n\t}\n\n\t/** Opens or closes the public tunnel (used by the `t` key). */\n\tpublic toggleTunnel(): Promise<void> {\n\t\treturn this.tunnel.toggle();\n\t}\n\n\t/**\n\t * Stops the watcher and the bot. Safe to call more than once.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tthis.#stopped = true;\n\t\tthis.#clearRestartTimer();\n\t\tif (this.#healthTimer) clearInterval(this.#healthTimer);\n\t\tthis.#healthTimer = null;\n\t\tawait this.#enqueue(async () => {\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.builder.close(),\n\t\t\t\tthis.supervisor.stop(),\n\t\t\t\tthis.typechecker.close(),\n\t\t\t\tthis.tunnel.close(),\n\t\t\t\tthis.locales.close()\n\t\t\t]);\n\t\t});\n\t}\n\n\tpublic clearLogs(): void {\n\t\tthis.logs.clear();\n\t}\n\n\t#onBuildSuccess(outcome: BuildOutcome): void {\n\t\ttry {\n\t\t\tthis.locales.copy();\n\t\t} catch (error) {\n\t\t\tthis.#onBuildFailure({\n\t\t\t\t...outcome,\n\t\t\t\tok: false,\n\t\t\t\tmessage: `Failed to copy locales: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.#lastBuild = outcome;\n\t\tthis.#progress = { ...this.#progress, fraction: 0.75, message: 'starting the bot' };\n\t\tthis.#setBuild('ok');\n\t\tif (this.#stopped) return;\n\t\t// A checker without a watch mode (`tsz`) only knows about the change once the build is through.\n\t\tthis.typechecker.check();\n\t\tthis.log('stars', 'success', this.builder.tool === 'none' ? 'Sources changed' : `Build succeeded in ${outcome.durationMs}ms`);\n\t\tthis.#scheduleRestart(this.supervisor.state === 'idle' ? 'initial' : 'build');\n\t}\n\n\t#onBuildFailure(outcome: BuildOutcome): void {\n\t\tthis.#lastBuild = outcome;\n\t\tthis.#setBuild('failed');\n\t\tthis.#clearRestartTimer();\n\t\tthis.log('stars', 'error', `Build failed${outcome.message ? `: ${outcome.message}` : ''}, waiting for changes`);\n\t}\n\n\t#onExit(exit: ProcessExit): void {\n\t\tthis.#lastExit = exit;\n\t\tthis.#health = 'unknown';\n\t\tif (!exit.requested) {\n\t\t\tconst how = exit.signal ? `signal ${exit.signal}` : `code ${exit.code}`;\n\t\t\tthis.log('stars', exit.code === 0 ? 'warn' : 'error', `The bot exited with ${how}, waiting for changes (press r to restart)`);\n\t\t}\n\t\tthis.#emitStatus();\n\t}\n\n\t#scheduleRestart(reason: RestartReason): void {\n\t\tthis.#pendingReason = reason;\n\t\tthis.#clearRestartTimer();\n\t\tthis.#restartTimer = setTimeout(() => {\n\t\t\tthis.#restartTimer = null;\n\t\t\tconst pending = this.#pendingReason ?? reason;\n\t\t\tthis.#pendingReason = null;\n\t\t\tvoid this.restart(pending);\n\t\t}, this.config.dev.debounce);\n\t}\n\n\t#clearRestartTimer(): void {\n\t\tif (this.#restartTimer) clearTimeout(this.#restartTimer);\n\t\tthis.#restartTimer = null;\n\t}\n\n\t#enqueue(task: () => Promise<void>): Promise<void> {\n\t\tthis.#queue = this.#queue.then(task, task);\n\t\treturn this.#queue;\n\t}\n\n\t#setBuild(state: BuildState): void {\n\t\tif (this.#build === state) return;\n\t\tthis.#build = state;\n\t\tthis.#emitStatus();\n\t}\n\n\tasync #checkHealth(): Promise<void> {\n\t\tif (!this.supervisor.running || !this.config.dev.url || !this.config.dev.health) return;\n\t\tconst pid = this.supervisor.pid;\n\n\t\tlet next: HealthState;\n\t\ttry {\n\t\t\tconst response = await fetch(new URL(this.config.dev.health, this.config.dev.url), { signal: AbortSignal.timeout(2000) });\n\t\t\tnext = response.status < 500 ? 'ok' : 'down';\n\t\t} catch {\n\t\t\tnext = 'down';\n\t\t}\n\n\t\tif (this.#stopped || pid !== this.supervisor.pid) return;\n\t\tif (next !== this.#health) {\n\t\t\tthis.#health = next;\n\t\t\tif (next === 'ok') this.#settleProgress();\n\t\t\tthis.#emitStatus();\n\t\t}\n\t}\n\n\t#settleProgress(): void {\n\t\tif (this.config.dev.health && this.#health !== 'ok') return;\n\t\tif (this.#build !== 'ok') return;\n\t\tthis.#progress = {\n\t\t\t...this.#progress,\n\t\t\tfraction: 1,\n\t\t\tmessage: 'watching for changes',\n\t\t\treadyMs: this.#progress.readyMs ?? Date.now() - this.#progress.startedAt\n\t\t};\n\t}\n\n\t#emitStatus(): void {\n\t\tthis.emit('status', this.status);\n\t}\n}\n\nexport function createSupervisor(config: ResolvedStarsConfig): ProcessSupervisor {\n\treturn new ProcessSupervisor({\n\t\tcommand: process.execPath,\n\t\targs: [...config.dev.nodeArgs, config.build.output, ...config.dev.args],\n\t\tcwd: config.root,\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...config.dev.env,\n\t\t\tSTARS_DEV: '1',\n\t\t\tNODE_ENV: 'development',\n\t\t\tFORCE_COLOR: process.env.NO_COLOR !== undefined ? undefined : (process.env.FORCE_COLOR ?? (process.stdout.isTTY ? '1' : undefined))\n\t\t},\n\t\tkillTimeout: config.dev.killTimeout\n\t});\n}\n\nexport function describeReason(reason: RestartReason): string {\n\tswitch (reason) {\n\t\tcase 'initial':\n\t\t\treturn 'first build';\n\t\tcase 'build':\n\t\t\treturn 'sources changed';\n\t\tcase 'manual':\n\t\t\treturn 'manual restart';\n\t\tcase 'crash':\n\t\t\treturn 'after crash';\n\t}\n}\n","import { lookup } from 'node:dns/promises';\n\n/**\n * Resolves `localhost` the way Vite's dev server does: Node's default DNS result order (`dns.lookup('localhost')`)\n * can disagree with the OS's own, \"verbatim\" resolution order — a well known source of a dev URL that prints fine\n * but is not the address the bot actually bound to (e.g. an IPv6-first system where the server listens on IPv4\n * only). When the two disagree this returns the OS's own address instead of the literal `localhost` hostname.\n */\nexport async function resolveLocalhost(): Promise<string> {\n\ttry {\n\t\tconst [ordered, verbatim] = await Promise.all([lookup('localhost'), lookup('localhost', { verbatim: true })]);\n\t\treturn ordered.family === verbatim.family && ordered.address === verbatim.address ? 'localhost' : verbatim.address;\n\t} catch {\n\t\treturn 'localhost';\n\t}\n}\n\n/**\n * Replaces a `localhost` hostname in `url` with {@link resolveLocalhost}'s result. Any other hostname (an explicit\n * `dev.url` override, a LAN address, …) is returned untouched.\n */\nexport async function withResolvedLocalhost(url: string): Promise<string> {\n\tconst parsed = new URL(url);\n\tif (parsed.hostname !== 'localhost') return url;\n\n\tconst host = await resolveLocalhost();\n\tif (host === 'localhost') return url;\n\n\tparsed.hostname = host.includes(':') ? `[${host}]` : host;\n\treturn parsed.href;\n}\n","import { createWriteStream, mkdirSync, type WriteStream } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { LogBuffer, LogEntry } from './log-buffer.js';\n\n/**\n * Mirrors a dev session's logs into a file, so a run can be read back after the terminal UI is gone (the TUI takes\n * over the alternate screen and its scrollback disappears on exit). Seedcord keeps a `logs/` directory for the same\n * reason; this writes a single, truncated-per-run file instead.\n */\nexport class LogFileWriter {\n\t#stream: WriteStream | null = null;\n\n\tpublic constructor(\n\t\tpublic readonly file: string,\n\t\tprivate readonly logs: LogBuffer\n\t) {}\n\n\tpublic open(): void {\n\t\tif (this.#stream) return;\n\n\t\tmkdirSync(dirname(this.file), { recursive: true });\n\t\tthis.#stream = createWriteStream(this.file, { flags: 'w' });\n\t\t// A broken pipe or a read-only directory must never take the dev session down with it.\n\t\tthis.#stream.on('error', () => this.close());\n\n\t\tfor (const entry of this.logs.entries()) this.#write(entry);\n\t\tthis.logs.on('entry', this.#write);\n\t}\n\n\tpublic close(): void {\n\t\tconst stream = this.#stream;\n\t\tthis.#stream = null;\n\t\tif (!stream) return;\n\n\t\tthis.logs.off('entry', this.#write);\n\t\tstream.end();\n\t}\n\n\t#write = (entry: LogEntry): void => {\n\t\tthis.#stream?.write(`${format(entry)}\\n`);\n\t};\n}\n\nfunction format(entry: LogEntry): string {\n\treturn `${new Date(entry.time).toISOString()} ${entry.level.padEnd(7)} ${entry.source.padEnd(6)} ${entry.text}`;\n}\n","import { loadStarsConfig, type ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport type { ProjectArgs } from '../args.js';\nimport { resolveCwd } from '../args.js';\nimport { assertSupportedExperiments, createBuilder } from '../builders/index.js';\nimport { DevService } from '../dev-service.js';\nimport { ExitCode } from '../errors.js';\nimport { withResolvedLocalhost } from '../host.js';\nimport { LogFileWriter } from '../log-file.js';\nimport { prefersReducedMotion, resolveOutputMode, shouldUseColor } from '../output-mode.js';\nimport { prepareAutoImports } from './prepare.js';\n\nexport interface DevTaskOptions extends ProjectArgs {\n\ttui?: boolean;\n}\n\nexport async function runDev(options: DevTaskOptions): Promise<void> {\n\t// Dev mode applies to config evaluation, build plugins, and the supervised application — not only the child.\n\tprocess.env.NODE_ENV = 'development';\n\tconst config = await resolveDevConfig(\n\t\tawait loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config, env: { ...process.env, NODE_ENV: 'development' } })\n\t);\n\tassertSupportedExperiments(config);\n\tconst mode = resolveOutputMode({ tui: options.tui });\n\tconst color = shouldUseColor();\n\n\tconst service = new DevService(config, { builder: await createBuilder(config) });\n\tconst logFile = config.dev.logFile ? new LogFileWriter(config.dev.logFile, service.logs) : null;\n\tlogFile?.open();\n\tconst renderer =\n\t\tmode === 'tui'\n\t\t\t? (await import('../../renderers/tui.js')).createTuiRenderer(service, { color, reducedMotion: prefersReducedMotion() })\n\t\t\t: (await import('../../renderers/plain.js')).createPlainRenderer(service, { color });\n\n\tlet exiting: Promise<never> | null = null;\n\tconst shutdown = (code: ExitCode): Promise<never> => {\n\t\texiting ??= (async () => {\n\t\t\trenderer.stop();\n\t\t\tawait service.stop();\n\t\t\tlogFile?.close();\n\t\t\tprocess.exit(code);\n\t\t})();\n\t\treturn exiting;\n\t};\n\n\tprocess.once('SIGINT', () => void shutdown(ExitCode.Interrupted));\n\tprocess.once('SIGTERM', () => void shutdown(ExitCode.Terminated));\n\tprocess.once('SIGHUP', () => void shutdown(ExitCode.Terminated));\n\tif (process.platform !== 'win32') process.on('SIGUSR2', () => void service.restart('manual'));\n\n\tconst finished = renderer.start().then(() => shutdown(ExitCode.Ok));\n\ttry {\n\t\tawait prepareAutoImports(config);\n\t\tawait service.start();\n\t} catch (error) {\n\t\tservice.log('stars', 'error', error instanceof Error ? (error.stack ?? error.message) : String(error));\n\t\tawait shutdown(ExitCode.Error);\n\t}\n\tawait finished;\n}\n\n/**\n * Resolves `dev.url`'s `localhost` to the address that is actually reachable (see {@link withResolvedLocalhost}),\n * the way Vite's dev server does when it starts. Only `stars dev` pays this DNS lookup; `stars info`/`stars build`\n * show or use the unresolved config as-is, since they never talk to the bot.\n */\nasync function resolveDevConfig(config: ResolvedStarsConfig): Promise<ResolvedStarsConfig> {\n\tif (!config.dev.url) return config;\n\n\tconst url = await withResolvedLocalhost(config.dev.url);\n\treturn url === config.dev.url ? config : { ...config, dev: { ...config.dev, url } };\n}\n"],"mappings":"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"}
@@ -16,7 +16,7 @@ var dev_default = defineCommand({
16
16
  }
17
17
  },
18
18
  async run({ args }) {
19
- const { runDev } = await import("./dev-CWA_JVTb.js");
19
+ const { runDev } = await import("./dev-Dh1Euxk1.js");
20
20
  await runDev({
21
21
  config: args.config,
22
22
  cwd: args.cwd,
@@ -27,4 +27,4 @@ var dev_default = defineCommand({
27
27
 
28
28
  //#endregion
29
29
  export { dev_default as default };
30
- //# sourceMappingURL=dev-BCgaVd0m.js.map
30
+ //# sourceMappingURL=dev-hT1WR1Kh.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-BCgaVd0m.js","names":[],"sources":["../src/commands/dev.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport { projectArgs } from '../lib/args.js';\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'dev',\n\t\tdescription: 'Build, run and restart the bot on changes'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\ttui: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Interactive terminal UI; use --no-tui (or STARS_TUI=plain) for plain line output',\n\t\t\tdefault: true\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tconst { runDev } = await import('../lib/tasks/dev.js');\n\t\tawait runDev({ config: args.config, cwd: args.cwd, tui: args.tui ? undefined : false });\n\t}\n});\n"],"mappings":";;;;AAGA,kBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,KAAK;GACJ,MAAM;GACN,aAAa;GACb,SAAS;EACV;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,EAAE,WAAW,MAAM,OAAO;EAChC,MAAM,OAAO;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,KAAK,KAAK,MAAM,SAAY;EAAM,CAAC;CACvF;AACD,CAAC"}
1
+ {"version":3,"file":"dev-hT1WR1Kh.js","names":[],"sources":["../src/commands/dev.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport { projectArgs } from '../lib/args.js';\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'dev',\n\t\tdescription: 'Build, run and restart the bot on changes'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\ttui: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Interactive terminal UI; use --no-tui (or STARS_TUI=plain) for plain line output',\n\t\t\tdefault: true\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tconst { runDev } = await import('../lib/tasks/dev.js');\n\t\tawait runDev({ config: args.config, cwd: args.cwd, tui: args.tui ? undefined : false });\n\t}\n});\n"],"mappings":";;;;AAGA,kBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,KAAK;GACJ,MAAM;GACN,aAAa;GACb,SAAS;EACV;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,EAAE,WAAW,MAAM,OAAO;EAChC,MAAM,OAAO;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,KAAK,KAAK,MAAM,SAAY;EAAM,CAAC;CACvF;AACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"external-Bk4EESdT.js","names":["#watcher"],"sources":["../src/lib/builders/external.ts"],"sourcesContent":["import type { ResolvedStarsConfig, StarsBuildTool } from '@wolfstar/http-framework/config';\nimport { dirname } from 'node:path';\nimport { EventEmitter } from 'node:events';\nimport { displayPath } from '@wolfstar/http-framework/config';\nimport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n\n/**\n * Runs no build of its own: the project drives one itself (`vite dev`, `vite build --watch`, a task runner, …) and\n * this only watches what that build writes, restarting the bot whenever the output changes.\n *\n * This is what `experimental.enableExternalVite` selects — the CLI stays out of the build's way but keeps the rest\n * of `stars dev` (restarts, health, tunnel, type checking, the panel) working.\n */\nexport class ExternalBuilder extends EventEmitter<BuilderEvents> implements Builder {\n\tpublic readonly tool: StarsBuildTool;\n\t#watcher: { close(): Promise<void> } | null = null;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t\tthis.tool = config.build.tool;\n\t}\n\n\tpublic build(): Promise<BuildOutcome> {\n\t\tthis.emit('start');\n\t\tconst outcome: BuildOutcome = { ok: true, durationMs: 0, message: null };\n\t\tthis.emit('success', outcome);\n\t\treturn Promise.resolve(outcome);\n\t}\n\n\tpublic async watch(): Promise<void> {\n\t\tconst { watch } = await import('chokidar');\n\t\tconst target = dirname(this.config.build.output);\n\t\tthis.emit('log', 'info', `Watching ${displayPath(this.config.root, target)} for an external build`);\n\n\t\tconst watcher = watch(target, { ignored: [...this.config.dev.ignore], ignoreInitial: true, cwd: this.config.root });\n\t\tthis.#watcher = watcher;\n\n\t\twatcher.on('all', (event, path) => {\n\t\t\tthis.emit('log', 'info', `${event}: ${path}`);\n\t\t\tvoid this.build();\n\t\t});\n\t\twatcher.on('error', (error) => this.emit('log', 'error', error instanceof Error ? error.message : String(error)));\n\n\t\tawait new Promise<void>((resolve) => watcher.once('ready', resolve));\n\t\tawait this.build();\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tconst watcher = this.#watcher;\n\t\tthis.#watcher = null;\n\t\tawait watcher?.close();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,kBAAb,cAAqC,aAA+C;CAI/C;CAHpC,AAAgB;CAChB,WAA8C;CAE9C,AAAO,YAAY,AAAiB,QAA6B;EAChE,MAAM;EAD6B;EAEnC,KAAK,OAAO,OAAO,MAAM;CAC1B;CAEA,AAAO,QAA+B;EACrC,KAAK,KAAK,OAAO;EACjB,MAAM,UAAwB;GAAE,IAAI;GAAM,YAAY;GAAG,SAAS;EAAK;EACvE,KAAK,KAAK,WAAW,OAAO;EAC5B,OAAO,QAAQ,QAAQ,OAAO;CAC/B;CAEA,MAAa,QAAuB;EACnC,MAAM,EAAE,UAAU,MAAM,OAAO;EAC/B,MAAM,SAAS,QAAQ,KAAK,OAAO,MAAM,MAAM;EAC/C,KAAK,KAAK,OAAO,QAAQ,YAAY,YAAY,KAAK,OAAO,MAAM,MAAM,EAAE,uBAAuB;EAElG,MAAM,UAAU,MAAM,QAAQ;GAAE,SAAS,CAAC,GAAG,KAAK,OAAO,IAAI,MAAM;GAAG,eAAe;GAAM,KAAK,KAAK,OAAO;EAAK,CAAC;EAClH,KAAKA,WAAW;EAEhB,QAAQ,GAAG,QAAQ,OAAO,SAAS;GAClC,KAAK,KAAK,OAAO,QAAQ,GAAG,MAAM,IAAI,MAAM;GAC5C,AAAK,KAAK,MAAM;EACjB,CAAC;EACD,QAAQ,GAAG,UAAU,UAAU,KAAK,KAAK,OAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;EAEhH,MAAM,IAAI,SAAe,YAAY,QAAQ,KAAK,SAAS,OAAO,CAAC;EACnE,MAAM,KAAK,MAAM;CAClB;CAEA,MAAa,QAAuB;EACnC,MAAM,UAAU,KAAKA;EACrB,KAAKA,WAAW;EAChB,MAAM,SAAS,MAAM;CACtB;AACD"}
1
+ {"version":3,"file":"external-Bk4EESdT.js","names":[],"sources":["../src/lib/builders/external.ts"],"sourcesContent":["import type { ResolvedStarsConfig, StarsBuildTool } from '@wolfstar/http-framework/config';\nimport { dirname } from 'node:path';\nimport { EventEmitter } from 'node:events';\nimport { displayPath } from '@wolfstar/http-framework/config';\nimport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n\n/**\n * Runs no build of its own: the project drives one itself (`vite dev`, `vite build --watch`, a task runner, …) and\n * this only watches what that build writes, restarting the bot whenever the output changes.\n *\n * This is what `experimental.enableExternalVite` selects — the CLI stays out of the build's way but keeps the rest\n * of `stars dev` (restarts, health, tunnel, type checking, the panel) working.\n */\nexport class ExternalBuilder extends EventEmitter<BuilderEvents> implements Builder {\n\tpublic readonly tool: StarsBuildTool;\n\t#watcher: { close(): Promise<void> } | null = null;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t\tthis.tool = config.build.tool;\n\t}\n\n\tpublic build(): Promise<BuildOutcome> {\n\t\tthis.emit('start');\n\t\tconst outcome: BuildOutcome = { ok: true, durationMs: 0, message: null };\n\t\tthis.emit('success', outcome);\n\t\treturn Promise.resolve(outcome);\n\t}\n\n\tpublic async watch(): Promise<void> {\n\t\tconst { watch } = await import('chokidar');\n\t\tconst target = dirname(this.config.build.output);\n\t\tthis.emit('log', 'info', `Watching ${displayPath(this.config.root, target)} for an external build`);\n\n\t\tconst watcher = watch(target, { ignored: [...this.config.dev.ignore], ignoreInitial: true, cwd: this.config.root });\n\t\tthis.#watcher = watcher;\n\n\t\twatcher.on('all', (event, path) => {\n\t\t\tthis.emit('log', 'info', `${event}: ${path}`);\n\t\t\tvoid this.build();\n\t\t});\n\t\twatcher.on('error', (error) => this.emit('log', 'error', error instanceof Error ? error.message : String(error)));\n\n\t\tawait new Promise<void>((resolve) => watcher.once('ready', resolve));\n\t\tawait this.build();\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tconst watcher = this.#watcher;\n\t\tthis.#watcher = null;\n\t\tawait watcher?.close();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,kBAAb,cAAqC,aAA+C;CAI/C;CAHpC,AAAgB;CAChB,WAA8C;CAE9C,AAAO,YAAY,AAAiB,QAA6B;EAChE,MAAM;EAD6B;EAEnC,KAAK,OAAO,OAAO,MAAM;CAC1B;CAEA,AAAO,QAA+B;EACrC,KAAK,KAAK,OAAO;EACjB,MAAM,UAAwB;GAAE,IAAI;GAAM,YAAY;GAAG,SAAS;EAAK;EACvE,KAAK,KAAK,WAAW,OAAO;EAC5B,OAAO,QAAQ,QAAQ,OAAO;CAC/B;CAEA,MAAa,QAAuB;EACnC,MAAM,EAAE,UAAU,MAAM,OAAO;EAC/B,MAAM,SAAS,QAAQ,KAAK,OAAO,MAAM,MAAM;EAC/C,KAAK,KAAK,OAAO,QAAQ,YAAY,YAAY,KAAK,OAAO,MAAM,MAAM,EAAE,uBAAuB;EAElG,MAAM,UAAU,MAAM,QAAQ;GAAE,SAAS,CAAC,GAAG,KAAK,OAAO,IAAI,MAAM;GAAG,eAAe;GAAM,KAAK,KAAK,OAAO;EAAK,CAAC;EAClH,KAAK,WAAW;EAEhB,QAAQ,GAAG,QAAQ,OAAO,SAAS;GAClC,KAAK,KAAK,OAAO,QAAQ,GAAG,MAAM,IAAI,MAAM;GAC5C,AAAK,KAAK,MAAM;EACjB,CAAC;EACD,QAAQ,GAAG,UAAU,UAAU,KAAK,KAAK,OAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;EAEhH,MAAM,IAAI,SAAe,YAAY,QAAQ,KAAK,SAAS,OAAO,CAAC;EACnE,MAAM,KAAK,MAAM;CAClB;CAEA,MAAa,QAAuB;EACnC,MAAM,UAAU,KAAK;EACrB,KAAK,WAAW;EAChB,MAAM,SAAS,MAAM;CACtB;AACD"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ConfigError, ConfigErrorOptions, ResolvedStarsConfig, loadStarsConfig } from "@wolfstar/http-framework/config";
2
2
  //#region src/lib/errors.d.ts
3
- declare const ExitCode: {
3
+ export declare const ExitCode: {
4
4
  readonly Ok: 0;
5
5
  readonly Error: 1;
6
6
  readonly InvalidConfig: 2;
@@ -8,7 +8,7 @@ declare const ExitCode: {
8
8
  readonly Interrupted: 130;
9
9
  readonly Terminated: 143;
10
10
  };
11
- type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
11
+ export type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
12
12
  interface CliErrorOptions {
13
13
  /** A stable, machine readable code. */
14
14
  code: string;
@@ -20,7 +20,7 @@ interface CliErrorOptions {
20
20
  /**
21
21
  * An error the CLI reports to the user without a stack trace.
22
22
  */
23
- declare class CliError extends Error {
23
+ export declare class CliError extends Error {
24
24
  readonly code: string;
25
25
  readonly hint: string | null;
26
26
  readonly exitCode: ExitCode;
@@ -32,8 +32,8 @@ declare class CliError extends Error {
32
32
  * `ConfigError` comes from `@wolfstar/http-framework/config`: the framework validates `stars.config.*` and throws a
33
33
  * plain data error, the CLI decides how it looks on a terminal and which exit code it gets ({@link exitCodeOf}).
34
34
  */
35
- declare function formatError(error: unknown): string;
36
- declare function exitCodeOf(error: unknown): ExitCode;
35
+ export declare function formatError(error: unknown): string;
36
+ export declare function exitCodeOf(error: unknown): ExitCode;
37
37
  //#endregion
38
38
  //#region src/lib/output-mode.d.ts
39
39
  type OutputMode = 'tui' | 'plain';
@@ -43,6 +43,10 @@ interface ResolveOutputModeOptions {
43
43
  env?: NodeJS.ProcessEnv;
44
44
  /** Whether stdout is an interactive terminal. */
45
45
  isTTY?: boolean;
46
+ /** Raw-key input requires a terminal too, even when the output is a TTY. */
47
+ isInputTTY?: boolean;
48
+ columns?: number;
49
+ rows?: number;
46
50
  /** Whether the process runs in a CI environment. */
47
51
  isCI?: boolean;
48
52
  }
@@ -51,16 +55,16 @@ interface ResolveOutputModeOptions {
51
55
  *
52
56
  * Precedence: `--no-tui` › `STARS_TUI=plain` › non-interactive stdout, CI or `TERM=dumb`.
53
57
  */
54
- declare function resolveOutputMode(options?: ResolveOutputModeOptions): OutputMode;
55
- declare function isCIEnvironment(env?: NodeJS.ProcessEnv): boolean;
58
+ export declare function resolveOutputMode(options?: ResolveOutputModeOptions): OutputMode;
59
+ export declare function isCIEnvironment(env?: NodeJS.ProcessEnv): boolean;
56
60
  /**
57
61
  * Whether colours should be emitted, honouring `NO_COLOR` and `FORCE_COLOR`.
58
62
  */
59
- declare function shouldUseColor(env?: NodeJS.ProcessEnv, isTTY?: boolean): boolean;
63
+ export declare function shouldUseColor(env?: NodeJS.ProcessEnv, isTTY?: boolean): boolean;
60
64
  /**
61
65
  * Whether animations (spinners, blinking status) should be avoided.
62
66
  */
63
- declare function prefersReducedMotion(env?: NodeJS.ProcessEnv): boolean;
67
+ export declare function prefersReducedMotion(env?: NodeJS.ProcessEnv): boolean;
64
68
  //#endregion
65
- export { CliError, type CliErrorOptions, ConfigError, type ConfigErrorOptions, ExitCode, type OutputMode, type ResolveOutputModeOptions, type ResolvedStarsConfig, exitCodeOf, formatError, isCIEnvironment, loadStarsConfig, prefersReducedMotion, resolveOutputMode, shouldUseColor };
69
+ export { type CliErrorOptions, ConfigError, type ConfigErrorOptions, type OutputMode, type ResolveOutputModeOptions, type ResolvedStarsConfig, loadStarsConfig };
66
70
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/errors.ts","../src/lib/output-mode.ts"],"mappings":";;cAEa;WACZ;WACA;WACA;WACA;WACA;WACA;;KAGW,mBAAmB,uBAAuB;UAErC;;EAEhB;;EAEA;EACA,WAAW;EACX;;;;;cAMY,iBAAiB;WACb;WACA;WACA,UAAU;EAE1B,YAAmB,iBAAiB,SAAS;;;;;;;;iBAe9B,YAAY;iBAgBZ,WAAW,iBAAiB;;;KC7DhC;UAEK;;EAEhB;EACA,MAAM,OAAO;;EAEb;;EAEA;;;;;;;iBAUe,kBAAkB,UAAS,2BAAgC;iBAgB3D,gBAAgB,MAAK,OAAO;;;;iBAU5B,eAAe,MAAK,OAAO,YAA0B;;;;iBASrD,qBAAqB,MAAK,OAAO"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/errors.ts","../src/lib/output-mode.ts"],"mappings":";;qBAEa;WACZ;WACA;WACA;WACA;WACA;WACA;;YAGW,mBAAmB,uBAAuB;UAErC;;EAEhB;;EAEA;EACA,WAAW;EACX;;;;;qBAMY,iBAAiB;WACb;WACA;WACA,UAAU;EAE1B,YAAmB,iBAAiB,SAAS;;;;;;;;wBAe9B,YAAY;wBAgBZ,WAAW,iBAAiB;;;KC7DhC;UAEK;;EAEhB;EACA,MAAM,OAAO;;EAEb;;EAEA;EACA;EACA;;EAEA;;;;;;;wBAUe,kBAAkB,UAAS,2BAAgC;wBAkB3D,gBAAgB,MAAK,OAAO;;;;wBAU5B,eAAe,MAAK,OAAO,YAA0B;;;;wBASrD,qBAAqB,MAAK,OAAO"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as formatError, n as ExitCode, r as exitCodeOf, t as CliError } from "./errors-Bket6XFn.js";
2
- import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode, t as isCIEnvironment } from "./output-mode-ChrOf0LO.js";
2
+ import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode, t as isCIEnvironment } from "./output-mode-Cxes6YUW.js";
3
3
  import { ConfigError, loadStarsConfig } from "@wolfstar/http-framework/config";
4
4
 
5
5
  export { CliError, ConfigError, ExitCode, exitCodeOf, formatError, isCIEnvironment, loadStarsConfig, prefersReducedMotion, resolveOutputMode, shouldUseColor };
@@ -1,5 +1,5 @@
1
1
  import { t as readOwnPackageJson } from "./version-DN6Uho-Y.js";
2
- import { i as shouldUseColor, r as resolveOutputMode } from "./output-mode-ChrOf0LO.js";
2
+ import { i as shouldUseColor, r as resolveOutputMode } from "./output-mode-Cxes6YUW.js";
3
3
  import { n as resolveCwd } from "./args-Ch1KXUMn.js";
4
4
  import { t as findInstalledVersion } from "./project-DHF3qdm-.js";
5
5
  import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
@@ -115,4 +115,4 @@ async function runInfo(options) {
115
115
 
116
116
  //#endregion
117
117
  export { runInfo };
118
- //# sourceMappingURL=info-Czh4LUsD.js.map
118
+ //# sourceMappingURL=info-BrxKCcUW.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"info-Czh4LUsD.js","names":[],"sources":["../src/lib/tasks/info.ts"],"sourcesContent":["import { createColors } from 'colorette';\nimport { arch, platform } from 'node:os';\nimport { relative } from 'node:path';\nimport type { ProjectArgs } from '../args.js';\nimport { resolveCwd } from '../args.js';\nimport { loadStarsConfig } from '@wolfstar/http-framework/config';\nimport { displayPath, type ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { resolveOutputMode, shouldUseColor } from '../output-mode.js';\nimport { findInstalledVersion } from '../project.js';\nimport { readOwnPackageJson } from '../version.js';\n\nexport interface InfoOptions extends ProjectArgs {\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\nexport interface ProjectInfo {\n\tcli: { version: string; node: string; platform: string; outputMode: 'tui' | 'plain' };\n\tproject: {\n\t\tcwd: string;\n\t\troot: string;\n\t\tconfigFile: string | null;\n\t\tname: string | null;\n\t\tversion: string | null;\n\t\tentry: string;\n\t\tframeworkVersion: string | null;\n\t};\n\tbuild: ResolvedStarsConfig['build'];\n\tdev: ResolvedStarsConfig['dev'];\n\tcodegen: ResolvedStarsConfig['codegen'];\n\timports: ResolvedStarsConfig['imports'];\n\texperimental: ResolvedStarsConfig['experimental'];\n\tfuture: ResolvedStarsConfig['future'];\n\t/**\n\t * The option names set in the `tsdown`/`vite` blocks. Only the names: the values hold plugins and callbacks,\n\t * which neither serialize to JSON nor read usefully on a terminal.\n\t */\n\toptions: { tsdown: string[]; vite: string[] };\n}\n\nexport function collectInfo(config: ResolvedStarsConfig): ProjectInfo {\n\treturn {\n\t\tcli: {\n\t\t\tversion: readOwnPackageJson().version,\n\t\t\tnode: process.version,\n\t\t\tplatform: `${platform()} ${arch()}`,\n\t\t\toutputMode: resolveOutputMode()\n\t\t},\n\t\tproject: {\n\t\t\tcwd: config.cwd,\n\t\t\troot: config.root,\n\t\t\tconfigFile: config.configFile,\n\t\t\tname: config.packageJson?.name ?? null,\n\t\t\tversion: config.packageJson?.version ?? null,\n\t\t\tentry: config.entry,\n\t\t\tframeworkVersion: findInstalledVersion(config.root, '@wolfstar/http-framework')\n\t\t},\n\t\tbuild: config.build,\n\t\tdev: config.dev,\n\t\tcodegen: config.codegen,\n\t\timports: config.imports,\n\t\texperimental: config.experimental,\n\t\tfuture: config.future,\n\t\toptions: { tsdown: Object.keys(config.tsdown), vite: Object.keys(config.vite) }\n\t};\n}\n\nexport function formatInfo(info: ProjectInfo, useColor: boolean): string {\n\tconst colors = createColors({ useColor });\n\tconst { root } = info.project;\n\tconst show = (path: string | null) => (path === null ? colors.dim('none') : displayPath(root, path));\n\tconst row = (label: string, value: string) => ` ${colors.dim(label.padEnd(12))}${value}`;\n\tconst section = (title: string, rows: string[]) => [colors.bold(title), ...rows].join('\\n');\n\n\treturn [\n\t\tsection(`stars ${colors.green(`v${info.cli.version}`)}`, [\n\t\t\trow('node', info.cli.node),\n\t\t\trow('platform', info.cli.platform),\n\t\t\trow('output', info.cli.outputMode),\n\t\t\trow(\n\t\t\t\t'framework',\n\t\t\t\tinfo.project.frameworkVersion\n\t\t\t\t\t? `@wolfstar/http-framework v${info.project.frameworkVersion}`\n\t\t\t\t\t: colors.yellow('@wolfstar/http-framework not installed')\n\t\t\t)\n\t\t]),\n\t\tsection('Project', [\n\t\t\trow(\n\t\t\t\t'name',\n\t\t\t\tinfo.project.name\n\t\t\t\t\t? `${info.project.name}${info.project.version ? colors.dim(` v${info.project.version}`) : ''}`\n\t\t\t\t\t: colors.dim('unnamed')\n\t\t\t),\n\t\t\trow('root', root),\n\t\t\trow(\n\t\t\t\t'config',\n\t\t\t\tinfo.project.configFile ? relative(root, info.project.configFile) || info.project.configFile : colors.dim('none (defaults)')\n\t\t\t),\n\t\t\trow('entry', show(info.project.entry))\n\t\t]),\n\t\tsection('Build', [\n\t\t\trow('tool', info.build.tool),\n\t\t\t// Which file the build tool is configured from: its own, or this project's `stars.config`.\n\t\t\trow('config', info.build.configFile ? show(info.build.configFile) : colors.dim('stars.config')),\n\t\t\trow('options', describeOptions(info, colors)),\n\t\t\trow('outDir', show(info.build.outDir)),\n\t\t\trow('tsconfig', show(info.build.tsconfig)),\n\t\t\trow('runs', show(info.build.output))\n\t\t]),\n\t\tsection('Dev', [\n\t\t\trow('watch', info.dev.watch.map(show).join(', ')),\n\t\t\trow('debounce', `${info.dev.debounce}ms`),\n\t\t\trow('node args', info.dev.nodeArgs.join(' ') || colors.dim('none')),\n\t\t\trow('args', info.dev.args.join(' ') || colors.dim('none')),\n\t\t\trow('url', info.dev.url ?? colors.dim('unknown, set dev.url or HTTP_PORT')),\n\t\t\trow('health', info.dev.health ?? colors.dim('none')),\n\t\t\trow(\n\t\t\t\t'typecheck',\n\t\t\t\tinfo.dev.typecheck.enabled ? `${info.dev.typecheck.checker} → ${show(info.dev.typecheck.tsconfig)}` : colors.dim('disabled')\n\t\t\t),\n\t\t\trow('tunnel', describeTunnel(info.dev.tunnel, colors)),\n\t\t\trow('log file', info.dev.logFile ? show(info.dev.logFile) : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Codegen', [\n\t\t\trow('i18n', info.codegen.i18n ? `${show(info.codegen.i18n.locales)} → ${show(info.codegen.i18n.output)}` : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Future', [row('compat', `v${info.future.compatibilityVersion} defaults`)]),\n\t\tsection('Experimental', [\n\t\t\trow('vite', flag(info.experimental.enableVite, colors)),\n\t\t\trow('nitro', flag(info.experimental.enableNitro, colors)),\n\t\t\trow('external', flag(info.experimental.enableExternalVite, colors))\n\t\t]),\n\t\tsection('Imports', [\n\t\t\trow('auto', info.imports.enabled ? colors.green('enabled') : colors.dim('disabled')),\n\t\t\trow('dirs', info.imports.dirs.map(show).join(', ')),\n\t\t\trow('presets', info.imports.presets.join(', ') || colors.dim('none')),\n\t\t\trow('dts', show(info.imports.dts))\n\t\t])\n\t].join('\\n\\n');\n}\n\nfunction describeOptions(info: ProjectInfo, colors: ReturnType<typeof createColors>): string {\n\tconst names = info.build.tool === 'vite' ? info.options.vite : info.options.tsdown;\n\treturn names.length > 0 ? names.join(', ') : colors.dim('none');\n}\n\nfunction flag(enabled: boolean, colors: ReturnType<typeof createColors>): string {\n\treturn enabled ? colors.green('enabled') : colors.dim('disabled');\n}\n\nfunction describeTunnel(tunnel: ResolvedStarsConfig['dev']['tunnel'], colors: ReturnType<typeof createColors>): string {\n\tswitch (tunnel.mode) {\n\t\tcase 'quick':\n\t\t\treturn 'cloudflared quick tunnel';\n\t\tcase 'url':\n\t\t\treturn tunnel.url;\n\t\tdefault:\n\t\t\treturn colors.dim('disabled');\n\t}\n}\n\nexport async function runInfo(options: InfoOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst config = await loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config });\n\tconst info = collectInfo(config);\n\tstdout.write(`${options.json ? JSON.stringify(info, null, 2) : formatInfo(info, shouldUseColor())}\\n`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"info-BrxKCcUW.js","names":[],"sources":["../src/lib/tasks/info.ts"],"sourcesContent":["import { createColors } from 'colorette';\nimport { arch, platform } from 'node:os';\nimport { relative } from 'node:path';\nimport type { ProjectArgs } from '../args.js';\nimport { resolveCwd } from '../args.js';\nimport { loadStarsConfig } from '@wolfstar/http-framework/config';\nimport { displayPath, type ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { resolveOutputMode, shouldUseColor } from '../output-mode.js';\nimport { findInstalledVersion } from '../project.js';\nimport { readOwnPackageJson } from '../version.js';\n\nexport interface InfoOptions extends ProjectArgs {\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\nexport interface ProjectInfo {\n\tcli: { version: string; node: string; platform: string; outputMode: 'tui' | 'plain' };\n\tproject: {\n\t\tcwd: string;\n\t\troot: string;\n\t\tconfigFile: string | null;\n\t\tname: string | null;\n\t\tversion: string | null;\n\t\tentry: string;\n\t\tframeworkVersion: string | null;\n\t};\n\tbuild: ResolvedStarsConfig['build'];\n\tdev: ResolvedStarsConfig['dev'];\n\tcodegen: ResolvedStarsConfig['codegen'];\n\timports: ResolvedStarsConfig['imports'];\n\texperimental: ResolvedStarsConfig['experimental'];\n\tfuture: ResolvedStarsConfig['future'];\n\t/**\n\t * The option names set in the `tsdown`/`vite` blocks. Only the names: the values hold plugins and callbacks,\n\t * which neither serialize to JSON nor read usefully on a terminal.\n\t */\n\toptions: { tsdown: string[]; vite: string[] };\n}\n\nexport function collectInfo(config: ResolvedStarsConfig): ProjectInfo {\n\treturn {\n\t\tcli: {\n\t\t\tversion: readOwnPackageJson().version,\n\t\t\tnode: process.version,\n\t\t\tplatform: `${platform()} ${arch()}`,\n\t\t\toutputMode: resolveOutputMode()\n\t\t},\n\t\tproject: {\n\t\t\tcwd: config.cwd,\n\t\t\troot: config.root,\n\t\t\tconfigFile: config.configFile,\n\t\t\tname: config.packageJson?.name ?? null,\n\t\t\tversion: config.packageJson?.version ?? null,\n\t\t\tentry: config.entry,\n\t\t\tframeworkVersion: findInstalledVersion(config.root, '@wolfstar/http-framework')\n\t\t},\n\t\tbuild: config.build,\n\t\tdev: config.dev,\n\t\tcodegen: config.codegen,\n\t\timports: config.imports,\n\t\texperimental: config.experimental,\n\t\tfuture: config.future,\n\t\toptions: { tsdown: Object.keys(config.tsdown), vite: Object.keys(config.vite) }\n\t};\n}\n\nexport function formatInfo(info: ProjectInfo, useColor: boolean): string {\n\tconst colors = createColors({ useColor });\n\tconst { root } = info.project;\n\tconst show = (path: string | null) => (path === null ? colors.dim('none') : displayPath(root, path));\n\tconst row = (label: string, value: string) => ` ${colors.dim(label.padEnd(12))}${value}`;\n\tconst section = (title: string, rows: string[]) => [colors.bold(title), ...rows].join('\\n');\n\n\treturn [\n\t\tsection(`stars ${colors.green(`v${info.cli.version}`)}`, [\n\t\t\trow('node', info.cli.node),\n\t\t\trow('platform', info.cli.platform),\n\t\t\trow('output', info.cli.outputMode),\n\t\t\trow(\n\t\t\t\t'framework',\n\t\t\t\tinfo.project.frameworkVersion\n\t\t\t\t\t? `@wolfstar/http-framework v${info.project.frameworkVersion}`\n\t\t\t\t\t: colors.yellow('@wolfstar/http-framework not installed')\n\t\t\t)\n\t\t]),\n\t\tsection('Project', [\n\t\t\trow(\n\t\t\t\t'name',\n\t\t\t\tinfo.project.name\n\t\t\t\t\t? `${info.project.name}${info.project.version ? colors.dim(` v${info.project.version}`) : ''}`\n\t\t\t\t\t: colors.dim('unnamed')\n\t\t\t),\n\t\t\trow('root', root),\n\t\t\trow(\n\t\t\t\t'config',\n\t\t\t\tinfo.project.configFile ? relative(root, info.project.configFile) || info.project.configFile : colors.dim('none (defaults)')\n\t\t\t),\n\t\t\trow('entry', show(info.project.entry))\n\t\t]),\n\t\tsection('Build', [\n\t\t\trow('tool', info.build.tool),\n\t\t\t// Which file the build tool is configured from: its own, or this project's `stars.config`.\n\t\t\trow('config', info.build.configFile ? show(info.build.configFile) : colors.dim('stars.config')),\n\t\t\trow('options', describeOptions(info, colors)),\n\t\t\trow('outDir', show(info.build.outDir)),\n\t\t\trow('tsconfig', show(info.build.tsconfig)),\n\t\t\trow('runs', show(info.build.output))\n\t\t]),\n\t\tsection('Dev', [\n\t\t\trow('watch', info.dev.watch.map(show).join(', ')),\n\t\t\trow('debounce', `${info.dev.debounce}ms`),\n\t\t\trow('node args', info.dev.nodeArgs.join(' ') || colors.dim('none')),\n\t\t\trow('args', info.dev.args.join(' ') || colors.dim('none')),\n\t\t\trow('url', info.dev.url ?? colors.dim('unknown, set dev.url or HTTP_PORT')),\n\t\t\trow('health', info.dev.health ?? colors.dim('none')),\n\t\t\trow(\n\t\t\t\t'typecheck',\n\t\t\t\tinfo.dev.typecheck.enabled ? `${info.dev.typecheck.checker} → ${show(info.dev.typecheck.tsconfig)}` : colors.dim('disabled')\n\t\t\t),\n\t\t\trow('tunnel', describeTunnel(info.dev.tunnel, colors)),\n\t\t\trow('log file', info.dev.logFile ? show(info.dev.logFile) : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Codegen', [\n\t\t\trow('i18n', info.codegen.i18n ? `${show(info.codegen.i18n.locales)} → ${show(info.codegen.i18n.output)}` : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Future', [row('compat', `v${info.future.compatibilityVersion} defaults`)]),\n\t\tsection('Experimental', [\n\t\t\trow('vite', flag(info.experimental.enableVite, colors)),\n\t\t\trow('nitro', flag(info.experimental.enableNitro, colors)),\n\t\t\trow('external', flag(info.experimental.enableExternalVite, colors))\n\t\t]),\n\t\tsection('Imports', [\n\t\t\trow('auto', info.imports.enabled ? colors.green('enabled') : colors.dim('disabled')),\n\t\t\trow('dirs', info.imports.dirs.map(show).join(', ')),\n\t\t\trow('presets', info.imports.presets.join(', ') || colors.dim('none')),\n\t\t\trow('dts', show(info.imports.dts))\n\t\t])\n\t].join('\\n\\n');\n}\n\nfunction describeOptions(info: ProjectInfo, colors: ReturnType<typeof createColors>): string {\n\tconst names = info.build.tool === 'vite' ? info.options.vite : info.options.tsdown;\n\treturn names.length > 0 ? names.join(', ') : colors.dim('none');\n}\n\nfunction flag(enabled: boolean, colors: ReturnType<typeof createColors>): string {\n\treturn enabled ? colors.green('enabled') : colors.dim('disabled');\n}\n\nfunction describeTunnel(tunnel: ResolvedStarsConfig['dev']['tunnel'], colors: ReturnType<typeof createColors>): string {\n\tswitch (tunnel.mode) {\n\t\tcase 'quick':\n\t\t\treturn 'cloudflared quick tunnel';\n\t\tcase 'url':\n\t\t\treturn tunnel.url;\n\t\tdefault:\n\t\t\treturn colors.dim('disabled');\n\t}\n}\n\nexport async function runInfo(options: InfoOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst config = await loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config });\n\tconst info = collectInfo(config);\n\tstdout.write(`${options.json ? JSON.stringify(info, null, 2) : formatInfo(info, shouldUseColor())}\\n`);\n}\n"],"mappings":";;;;;;;;;;AAwCA,SAAgB,YAAY,QAA0C;CACrE,OAAO;EACN,KAAK;GACJ,SAAS,mBAAmB,CAAC,CAAC;GAC9B,MAAM,QAAQ;GACd,UAAU,GAAG,SAAS,EAAE,GAAG,KAAK;GAChC,YAAY,kBAAkB;EAC/B;EACA,SAAS;GACR,KAAK,OAAO;GACZ,MAAM,OAAO;GACb,YAAY,OAAO;GACnB,MAAM,OAAO,aAAa,QAAQ;GAClC,SAAS,OAAO,aAAa,WAAW;GACxC,OAAO,OAAO;GACd,kBAAkB,qBAAqB,OAAO,MAAM,0BAA0B;EAC/E;EACA,OAAO,OAAO;EACd,KAAK,OAAO;EACZ,SAAS,OAAO;EAChB,SAAS,OAAO;EAChB,cAAc,OAAO;EACrB,QAAQ,OAAO;EACf,SAAS;GAAE,QAAQ,OAAO,KAAK,OAAO,MAAM;GAAG,MAAM,OAAO,KAAK,OAAO,IAAI;EAAE;CAC/E;AACD;AAEA,SAAgB,WAAW,MAAmB,UAA2B;CACxE,MAAM,SAAS,aAAa,EAAE,SAAS,CAAC;CACxC,MAAM,EAAE,SAAS,KAAK;CACtB,MAAM,QAAQ,SAAyB,SAAS,OAAO,OAAO,IAAI,MAAM,IAAI,YAAY,MAAM,IAAI;CAClG,MAAM,OAAO,OAAe,UAAkB,KAAK,OAAO,IAAI,MAAM,OAAO,EAAE,CAAC,IAAI;CAClF,MAAM,WAAW,OAAe,SAAmB,CAAC,OAAO,KAAK,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI;CAE1F,OAAO;EACN,QAAQ,SAAS,OAAO,MAAM,IAAI,KAAK,IAAI,SAAS,KAAK;GACxD,IAAI,QAAQ,KAAK,IAAI,IAAI;GACzB,IAAI,YAAY,KAAK,IAAI,QAAQ;GACjC,IAAI,UAAU,KAAK,IAAI,UAAU;GACjC,IACC,aACA,KAAK,QAAQ,mBACV,6BAA6B,KAAK,QAAQ,qBAC1C,OAAO,OAAO,wCAAwC,CAC1D;EACD,CAAC;EACD,QAAQ,WAAW;GAClB,IACC,QACA,KAAK,QAAQ,OACV,GAAG,KAAK,QAAQ,OAAO,KAAK,QAAQ,UAAU,OAAO,IAAI,KAAK,KAAK,QAAQ,SAAS,IAAI,OACxF,OAAO,IAAI,SAAS,CACxB;GACA,IAAI,QAAQ,IAAI;GAChB,IACC,UACA,KAAK,QAAQ,aAAa,SAAS,MAAM,KAAK,QAAQ,UAAU,KAAK,KAAK,QAAQ,aAAa,OAAO,IAAI,iBAAiB,CAC5H;GACA,IAAI,SAAS,KAAK,KAAK,QAAQ,KAAK,CAAC;EACtC,CAAC;EACD,QAAQ,SAAS;GAChB,IAAI,QAAQ,KAAK,MAAM,IAAI;GAE3B,IAAI,UAAU,KAAK,MAAM,aAAa,KAAK,KAAK,MAAM,UAAU,IAAI,OAAO,IAAI,cAAc,CAAC;GAC9F,IAAI,WAAW,gBAAgB,MAAM,MAAM,CAAC;GAC5C,IAAI,UAAU,KAAK,KAAK,MAAM,MAAM,CAAC;GACrC,IAAI,YAAY,KAAK,KAAK,MAAM,QAAQ,CAAC;GACzC,IAAI,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC;EACpC,CAAC;EACD,QAAQ,OAAO;GACd,IAAI,SAAS,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;GAChD,IAAI,YAAY,GAAG,KAAK,IAAI,SAAS,GAAG;GACxC,IAAI,aAAa,KAAK,IAAI,SAAS,KAAK,GAAG,KAAK,OAAO,IAAI,MAAM,CAAC;GAClE,IAAI,QAAQ,KAAK,IAAI,KAAK,KAAK,GAAG,KAAK,OAAO,IAAI,MAAM,CAAC;GACzD,IAAI,OAAO,KAAK,IAAI,OAAO,OAAO,IAAI,mCAAmC,CAAC;GAC1E,IAAI,UAAU,KAAK,IAAI,UAAU,OAAO,IAAI,MAAM,CAAC;GACnD,IACC,aACA,KAAK,IAAI,UAAU,UAAU,GAAG,KAAK,IAAI,UAAU,QAAQ,KAAK,KAAK,KAAK,IAAI,UAAU,QAAQ,MAAM,OAAO,IAAI,UAAU,CAC5H;GACA,IAAI,UAAU,eAAe,KAAK,IAAI,QAAQ,MAAM,CAAC;GACrD,IAAI,YAAY,KAAK,IAAI,UAAU,KAAK,KAAK,IAAI,OAAO,IAAI,OAAO,IAAI,UAAU,CAAC;EACnF,CAAC;EACD,QAAQ,WAAW,CAClB,IAAI,QAAQ,KAAK,QAAQ,OAAO,GAAG,KAAK,KAAK,QAAQ,KAAK,OAAO,EAAE,KAAK,KAAK,KAAK,QAAQ,KAAK,MAAM,MAAM,OAAO,IAAI,UAAU,CAAC,CAClI,CAAC;EACD,QAAQ,UAAU,CAAC,IAAI,UAAU,IAAI,KAAK,OAAO,qBAAqB,UAAU,CAAC,CAAC;EAClF,QAAQ,gBAAgB;GACvB,IAAI,QAAQ,KAAK,KAAK,aAAa,YAAY,MAAM,CAAC;GACtD,IAAI,SAAS,KAAK,KAAK,aAAa,aAAa,MAAM,CAAC;GACxD,IAAI,YAAY,KAAK,KAAK,aAAa,oBAAoB,MAAM,CAAC;EACnE,CAAC;EACD,QAAQ,WAAW;GAClB,IAAI,QAAQ,KAAK,QAAQ,UAAU,OAAO,MAAM,SAAS,IAAI,OAAO,IAAI,UAAU,CAAC;GACnF,IAAI,QAAQ,KAAK,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;GAClD,IAAI,WAAW,KAAK,QAAQ,QAAQ,KAAK,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC;GACpE,IAAI,OAAO,KAAK,KAAK,QAAQ,GAAG,CAAC;EAClC,CAAC;CACF,CAAC,CAAC,KAAK,MAAM;AACd;AAEA,SAAS,gBAAgB,MAAmB,QAAiD;CAC5F,MAAM,QAAQ,KAAK,MAAM,SAAS,SAAS,KAAK,QAAQ,OAAO,KAAK,QAAQ;CAC5E,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,IAAI,MAAM;AAC/D;AAEA,SAAS,KAAK,SAAkB,QAAiD;CAChF,OAAO,UAAU,OAAO,MAAM,SAAS,IAAI,OAAO,IAAI,UAAU;AACjE;AAEA,SAAS,eAAe,QAA8C,QAAiD;CACtH,QAAQ,OAAO,MAAf;EACC,KAAK,SACJ,OAAO;EACR,KAAK,OACJ,OAAO,OAAO;EACf,SACC,OAAO,OAAO,IAAI,UAAU;CAC9B;AACD;AAEA,eAAsB,QAAQ,SAAqC;CAClE,MAAM,SAAS,QAAQ,UAAU,QAAQ;CAEzC,MAAM,OAAO,YAAY,MADJ,gBAAgB;EAAE,KAAK,WAAW,OAAO;EAAG,YAAY,QAAQ;CAAO,CAAC,CAC9D;CAC/B,OAAO,MAAM,GAAG,QAAQ,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,WAAW,MAAM,eAAe,CAAC,EAAE,GAAG;AACtG"}
@@ -16,7 +16,7 @@ var info_default = defineCommand({
16
16
  }
17
17
  },
18
18
  async run({ args }) {
19
- const { runInfo } = await import("./info-Czh4LUsD.js");
19
+ const { runInfo } = await import("./info-BrxKCcUW.js");
20
20
  await runInfo({
21
21
  config: args.config,
22
22
  cwd: args.cwd,
@@ -27,4 +27,4 @@ var info_default = defineCommand({
27
27
 
28
28
  //#endregion
29
29
  export { info_default as default };
30
- //# sourceMappingURL=info-BqxpktLG.js.map
30
+ //# sourceMappingURL=info-rYRLITnv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"info-BqxpktLG.js","names":[],"sources":["../src/commands/info.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport { projectArgs } from '../lib/args.js';\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'info',\n\t\tdescription: 'Print the resolved project configuration and environment'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Print machine-readable JSON',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tconst { runInfo } = await import('../lib/tasks/info.js');\n\t\tawait runInfo({ config: args.config, cwd: args.cwd, json: args.json });\n\t}\n});\n"],"mappings":";;;;AAGA,mBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,MAAM;GACL,MAAM;GACN,aAAa;GACb,SAAS;EACV;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,QAAQ;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,MAAM,KAAK;EAAK,CAAC;CACtE;AACD,CAAC"}
1
+ {"version":3,"file":"info-rYRLITnv.js","names":[],"sources":["../src/commands/info.ts"],"sourcesContent":["import { defineCommand } from 'citty';\nimport { projectArgs } from '../lib/args.js';\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'info',\n\t\tdescription: 'Print the resolved project configuration and environment'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Print machine-readable JSON',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tconst { runInfo } = await import('../lib/tasks/info.js');\n\t\tawait runInfo({ config: args.config, cwd: args.cwd, json: args.json });\n\t}\n});\n"],"mappings":";;;;AAGA,mBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,MAAM;GACL,MAAM;GACN,aAAa;GACb,SAAS;EACV;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,QAAQ;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,MAAM,KAAK;EAAK,CAAC;CACtE;AACD,CAAC"}