seedcord 0.22.0-next.0 → 0.22.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.
package/bin/seedcord.mjs CHANGED
@@ -3,6 +3,8 @@ import { existsSync, readFileSync } from 'node:fs';
3
3
  import { dirname, resolve } from 'node:path';
4
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
5
5
 
6
+ import { isValid, isValidRange, satisfies } from 'verkit';
7
+
6
8
  const here = dirname(fileURLToPath(import.meta.url));
7
9
 
8
10
  function declaredEngines() {
@@ -14,24 +16,6 @@ function declaredEngines() {
14
16
  }
15
17
  }
16
18
 
17
- function parseVersion(text) {
18
- const [withoutBuild = ''] = text.replace(/^v/, '').split('+');
19
- const [release = '', ...prerelease] = withoutBuild.split('-');
20
- const parts = release.split('.').map(Number);
21
- return parts.every(Number.isInteger) ? { parts, prerelease: prerelease.length > 0 } : undefined;
22
- }
23
-
24
- // semver ranks 1.4.2-canary.1 below 1.4.2
25
- function meetsMinimum(required, running) {
26
- const length = Math.max(required.parts.length, running.parts.length);
27
- for (let index = 0; index < length; index++) {
28
- const wanted = required.parts[index] ?? 0;
29
- const got = running.parts[index] ?? 0;
30
- if (got !== wanted) return got > wanted;
31
- }
32
- return !running.prerelease;
33
- }
34
-
35
19
  // importing core's assertDeclaredRuntime here would load the code this guards
36
20
  function unsupportedRuntime() {
37
21
  const engines = declaredEngines();
@@ -41,12 +25,13 @@ function unsupportedRuntime() {
41
25
  ? { name: 'Node', range: engines.node ?? '', running: node }
42
26
  : { name: 'Bun', range: engines.bun ?? '', running: bun };
43
27
 
44
- const range = runtime.range.replaceAll(/\s/g, '');
45
- if (!range.startsWith('>=')) return undefined;
46
-
47
- const required = parseVersion(range.slice('>='.length));
48
- const running = parseVersion(runtime.running);
49
- if (!required || !running || meetsMinimum(required, running)) return undefined;
28
+ if (
29
+ !runtime.range ||
30
+ !isValidRange(runtime.range) ||
31
+ !isValid(runtime.running) ||
32
+ satisfies(runtime.running, runtime.range, { includePrerelease: true })
33
+ )
34
+ return undefined;
50
35
  return runtime;
51
36
  }
52
37
 
package/dist/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as SEEDCORD_CONFIG_FILENAMES, t as version } from "./src-BrsznVXh.mjs";
1
+ import { n as SEEDCORD_CONFIG_FILENAMES, t as version } from "./src-rYAuhl0h.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { Command, Option } from "@commander-js/extra-typings";
4
4
  import { SeedcordErrorCode, isSeedcordError, paint } from "@seedcord/errors";
@@ -14,14 +14,15 @@ import chalk from "chalk";
14
14
  import { basename, delimiter, dirname, join, posix, relative, resolve, win32 } from "node:path";
15
15
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
16
16
  import { CONSOLE_LEVEL, CONSOLE_METHODS, consoleRecord, logsFolderIn, routeConsole, traceError } from "@seedcord/logger/internal";
17
- import { BOT_FILES_KEY, BUILT_FILES_READY_KEY, BotLayout, asError, encodeFile, hasErrorCode, importFailed, isInside, isPlainObject, isPortInUse, isStringArray, pluralize, posixRelative, recordThrownBy, routeLeavesOf, setDevFiles, toPosixPath, unlessAborted, vitePluginThrew, withoutQuery, workerdPath } from "@seedcord/utils/internal";
17
+ import { BOT_FILES_KEY, BUILT_FILES_READY_KEY, BotLayout, asError, encodeFile, hasErrorCode, importFailed, isInside, isInteractive, isPlainObject, isPortInUse, isStringArray, pluralize, posixRelative, recordThrownBy, routeLeavesOf, setDevFiles, toPosixPath, unlessAborted, vitePluginThrew, withoutQuery, workerdPath } from "@seedcord/utils/internal";
18
18
  import { spawn } from "node:child_process";
19
19
  import { HostAugmentTarget, HostListenHost, HostPluginKeys, HostShutdown, HostStartup, HostVersion, SeedcordBrand } from "@seedcord/types/internal";
20
20
  import { Visitor, createBuilder, createLogger, createServer, createServerModuleRunner, loadEnv, mergeConfig, preview } from "vite";
21
+ import { fileURLToPath } from "node:url";
21
22
  import { format, parseEnv, stripVTControlCharacters } from "node:util";
23
+ import { BAKED_IDS_KEY, CommandMetadataKey, GLOBAL_ID, bindEnv, commandKey, commandRefOf, commandsRoute, currentApplication, fromDevLogLine, fromWireError, globalFirst, guildSummaries, isCommandClass, linkCommands, planDeploy, putCommands, readBotToken, readCommands, readCommandsAt, resolveDeployTarget, resolveEmojis, scopeIdsOf, skippedNote, warnLinks, wrapHot } from "@seedcord/core/internal";
24
+ import { Converters, ENVIRONMENT_KEYS, Envapter, Environment, PortableSource, merge } from "envapt";
22
25
  import { randomUUID } from "node:crypto";
23
- import { Converters, ENVIRONMENT_KEYS, Envapter, Environment, FileSource, PortableSource, merge } from "envapt";
24
- import { BAKED_IDS_KEY, CommandMetadataKey, GLOBAL_ID, commandKey, commandRefOf, commandsRoute, currentApplication, fromDevLogLine, fromWireError, globalFirst, guildSummaries, isCommandClass, linkCommands, planDeploy, putCommands, readBotToken, readCommands, readCommandsAt, resolveDeployTarget, resolveEmojis, scopeIdsOf, skippedNote, warnLinks, wrapHot } from "@seedcord/core/internal";
25
26
  import { DiscordAPIError, REST } from "@discordjs/rest";
26
27
  import "reflect-metadata";
27
28
  import { ApplicationCommandOptionType, ApplicationCommandType, InteractionContextType, RESTJSONErrorCodes, Routes } from "discord-api-types/v10";
@@ -1474,12 +1475,12 @@ var ProjectLoader = class {
1474
1475
  }
1475
1476
  async readConfig(projectDir = process.cwd(), check) {
1476
1477
  try {
1477
- var _usingCtx$7 = _usingCtx();
1478
+ var _usingCtx$8 = _usingCtx();
1478
1479
  const configPath = realPath(locateConfig(projectDir));
1479
1480
  const configDir = realPath(dirname(configPath));
1480
1481
  const mode = this.shell.applyMode(this.defaultMode, configDir);
1481
1482
  const target = detectTarget(configDir);
1482
- const stack = _usingCtx$7.a(new AsyncDisposableStack());
1483
+ const stack = _usingCtx$8.a(new AsyncDisposableStack());
1483
1484
  const configModules = stack.use(await this.openModules(configDir, target, mode, "config"));
1484
1485
  const config = await this.resolveConfig(configModules, configPath, target, mode);
1485
1486
  const project = new Project(config, new ProjectFiles(config), configModules);
@@ -1490,9 +1491,9 @@ var ProjectLoader = class {
1490
1491
  const loaded = new LoadedConfig(config, project.files);
1491
1492
  return loaded.hasVitePlugins ? new LoadedConfig(config, project.files, stack.move()) : loaded;
1492
1493
  } catch (_) {
1493
- _usingCtx$7.e = _;
1494
+ _usingCtx$8.e = _;
1494
1495
  } finally {
1495
- await _usingCtx$7.d();
1496
+ await _usingCtx$8.d();
1496
1497
  }
1497
1498
  }
1498
1499
  async openProject(loaded) {
@@ -1577,12 +1578,7 @@ function botEnvironment(environments) {
1577
1578
 
1578
1579
  //#endregion
1579
1580
  //#region src/core/modules/edgeStandIns.ts
1580
- const BIND_ENV_ID$1 = "seedcord:bind-env";
1581
- const RESOLVED_BIND_ENV_ID = `\0${BIND_ENV_ID$1}`;
1582
1581
  const CLOUDFLARE_WORKERS_ID = "\0seedcord:cloudflare-workers";
1583
- const bindEnv = (env) => `import { Envapter, PortableSource } from 'envapt';
1584
- Envapter.useSource(new PortableSource(${env}));
1585
- `;
1586
1582
  const cloudflareWorkers = (env) => `export const env = ${env};
1587
1583
  export const exports = {};
1588
1584
  export const cache = {};
@@ -1602,18 +1598,40 @@ function edgeStandIns(loadEnv) {
1602
1598
  return {
1603
1599
  name: "seedcord:edge-stand-ins",
1604
1600
  resolveId(id) {
1605
- if (id === "seedcord:bind-env") return RESOLVED_BIND_ENV_ID;
1606
1601
  if (id === "cloudflare:workers") return CLOUDFLARE_WORKERS_ID;
1607
1602
  },
1608
1603
  async load(id) {
1609
- if (id !== RESOLVED_BIND_ENV_ID && id !== CLOUDFLARE_WORKERS_ID) return void 0;
1604
+ if (id !== CLOUDFLARE_WORKERS_ID) return void 0;
1610
1605
  const workerEnv = await loadEnv();
1611
1606
  const values = JSON.stringify(workerEnv.values());
1612
- return id === RESOLVED_BIND_ENV_ID ? bindEnv(values) : cloudflareWorkers(values);
1607
+ return cloudflareWorkers(values);
1613
1608
  }
1614
1609
  };
1615
1610
  }
1616
1611
 
1612
+ //#endregion
1613
+ //#region src/core/modules/envBootstrap.ts
1614
+ const ENV_BOOTSTRAP_ID = "seedcord:env";
1615
+ const RESOLVED_ENV_BOOTSTRAP_ID = `\0${ENV_BOOTSTRAP_ID}`;
1616
+ function envBootstrapSource(options) {
1617
+ const helperPath = fileURLToPath(import.meta.resolve("@seedcord/core/internal/env"));
1618
+ const imports = `import { Envapter } from 'envapt';
1619
+ import { bindViteEnv } from ${JSON.stringify(helperPath)};\n`;
1620
+ if (options.runtime === "worker") return `${imports}import { env } from 'cloudflare:workers';
1621
+ export const binding = bindViteEnv(Envapter, import.meta.env, { bindings: env });\n`;
1622
+ if (options.directory !== void 0) return `${imports}export const binding = bindViteEnv(Envapter, import.meta.env, { directory: ${JSON.stringify(options.directory)} });\n`;
1623
+ const utilsPath = fileURLToPath(import.meta.resolve("@seedcord/utils/internal"));
1624
+ return `${imports}import { botConfigDir } from ${JSON.stringify(utilsPath)};
1625
+ export const binding = bindViteEnv(Envapter, import.meta.env, { directory: botConfigDir() });\n`;
1626
+ }
1627
+ function envBootstrap(options) {
1628
+ return {
1629
+ name: "seedcord:env",
1630
+ resolveId: (id) => id === "seedcord:env" ? RESOLVED_ENV_BOOTSTRAP_ID : void 0,
1631
+ load: (id) => id === RESOLVED_ENV_BOOTSTRAP_ID ? envBootstrapSource(options) : void 0
1632
+ };
1633
+ }
1634
+
1617
1635
  //#endregion
1618
1636
  //#region src/core/modules/openViteServer.ts
1619
1637
  function closesOn(stack) {
@@ -1651,6 +1669,7 @@ const IMPORT_DEADLINE_MS = 3e4;
1651
1669
  var RunnerModuleLoader = class {
1652
1670
  runner;
1653
1671
  deadlineMs;
1672
+ binding;
1654
1673
  constructor(runner, deadlineMs = IMPORT_DEADLINE_MS) {
1655
1674
  this.runner = runner;
1656
1675
  this.deadlineMs = deadlineMs;
@@ -1660,8 +1679,16 @@ var RunnerModuleLoader = class {
1660
1679
  if (!existsSync(path)) throw new SeedcordError(SeedcordErrorCode.CoreImportFailed, [path, "The file does not exist."]);
1661
1680
  return this.load(path, path);
1662
1681
  }
1663
- async bindEdgeEnv() {
1664
- await this.load(BIND_ENV_ID$1, "envapt");
1682
+ async bindEnv() {
1683
+ const { binding } = await this.load(ENV_BOOTSTRAP_ID, "envapt");
1684
+ this.binding = binding;
1685
+ }
1686
+ async [Symbol.asyncDispose]() {
1687
+ try {
1688
+ await this.runner.close();
1689
+ } finally {
1690
+ this.binding?.[Symbol.dispose]();
1691
+ }
1665
1692
  }
1666
1693
  async load(id, shownAs) {
1667
1694
  let timer;
@@ -1877,6 +1904,9 @@ var WorkerEnv = class WorkerEnv {
1877
1904
  static async load(cloudflareConfig, mode) {
1878
1905
  return new WorkerEnv(await loadWorker(cloudflareConfig, mode), cloudflareConfig, mode);
1879
1906
  }
1907
+ bindToCli(stack) {
1908
+ stack.use(bindEnv(Envapter, merge(Envapter.source, new PortableSource(this.values())), this.envDir));
1909
+ }
1880
1910
  values() {
1881
1911
  const local = this.localVars();
1882
1912
  const values = {};
@@ -1896,27 +1926,16 @@ var WorkerEnv = class WorkerEnv {
1896
1926
 
1897
1927
  //#endregion
1898
1928
  //#region src/core/modules/openModuleLoader.ts
1899
- var ViteModuleLoader = class extends RunnerModuleLoader {
1900
- server;
1901
- constructor(server, runner) {
1902
- super(runner);
1903
- this.server = server;
1904
- }
1905
- async [Symbol.asyncDispose]() {
1906
- await this.runner.close();
1907
- await this.server.close();
1908
- }
1909
- };
1910
1929
  function lazyWorkerEnv(cloudflareConfig, mode, loaded) {
1911
1930
  let loading = loaded && Promise.resolve(loaded);
1912
1931
  return () => loading ??= WorkerEnv.load(cloudflareConfig, mode);
1913
1932
  }
1914
1933
  async function openModuleLoader(projectDir, target, mode, use, devCopy) {
1915
1934
  try {
1916
- var _usingCtx$6 = _usingCtx();
1935
+ var _usingCtx$7 = _usingCtx();
1917
1936
  const runsWorkerCode = target.kind === "edge" && use !== "config";
1918
- const workerEnv = target.kind === "edge" ? lazyWorkerEnv(target.cloudflareConfig, mode, devCopy?.workerEnv) : void 0;
1919
- if (runsWorkerCode) await workerEnv?.();
1937
+ const loadWorkerEnv = target.kind === "edge" ? lazyWorkerEnv(target.cloudflareConfig, mode, devCopy?.workerEnv) : void 0;
1938
+ const workerEnv = runsWorkerCode && loadWorkerEnv ? await loadWorkerEnv() : void 0;
1920
1939
  const conditions = runsWorkerCode ? WORKERD_CONDITIONS : NODE_CONDITIONS;
1921
1940
  const userPlugins = use === "config" ? [] : use.vitePlugins.create();
1922
1941
  const config = mergeViteConfig(userCodeConfig(conditions, projectDir), {
@@ -1935,20 +1954,30 @@ async function openModuleLoader(projectDir, target, mode, use, devCopy) {
1935
1954
  noDiscovery: true,
1936
1955
  include: []
1937
1956
  },
1938
- plugins: [...workerEnv ? [edgeStandIns(workerEnv)] : [], userPlugins]
1957
+ plugins: [
1958
+ envBootstrap(runsWorkerCode ? { runtime: "worker" } : {
1959
+ runtime: "node",
1960
+ directory: projectDir
1961
+ }),
1962
+ ...loadWorkerEnv ? [edgeStandIns(loadWorkerEnv)] : [],
1963
+ userPlugins
1964
+ ]
1939
1965
  });
1940
- const onFailure = _usingCtx$6.a(new AsyncDisposableStack());
1966
+ const onFailure = _usingCtx$7.a(new AsyncDisposableStack());
1967
+ workerEnv?.bindToCli(onFailure);
1941
1968
  const server = await openViteServer(onFailure, config);
1942
1969
  const runner = createServerModuleRunner(botEnvironment(server.environments), { hmr: false });
1943
- onFailure.defer(() => runner.close());
1944
- const loader = new ViteModuleLoader(server, runner);
1945
- if (runsWorkerCode) await loader.bindEdgeEnv();
1946
- onFailure.move();
1947
- return loader;
1970
+ const loader = onFailure.use(new RunnerModuleLoader(runner));
1971
+ await loader.bindEnv();
1972
+ const resources = onFailure.move();
1973
+ return {
1974
+ importModule: loader.importModule.bind(loader),
1975
+ [Symbol.asyncDispose]: () => resources.disposeAsync()
1976
+ };
1948
1977
  } catch (_) {
1949
- _usingCtx$6.e = _;
1978
+ _usingCtx$7.e = _;
1950
1979
  } finally {
1951
- await _usingCtx$6.d();
1980
+ await _usingCtx$7.d();
1952
1981
  }
1953
1982
  }
1954
1983
 
@@ -1977,6 +2006,8 @@ function envFilesSetDevNodeEnv(mode, configDir) {
1977
2006
  }
1978
2007
  var ShellMode = class ShellMode {
1979
2008
  variable;
2009
+ nodeEnv = process.env.NODE_ENV;
2010
+ viteNodeEnv = process.env.VITE_USER_NODE_ENV;
1980
2011
  constructor(variable) {
1981
2012
  this.variable = variable;
1982
2013
  }
@@ -1993,7 +2024,12 @@ var ShellMode = class ShellMode {
1993
2024
  applyMode(defaultMode, configDir) {
1994
2025
  const mode = this.viteMode(defaultMode);
1995
2026
  Envapter.environment = mode;
1996
- process.env.NODE_ENV ||= envFilesSetDevNodeEnv(mode, configDir) ? "development" : defaultMode;
2027
+ if (this.nodeEnv) process.env.NODE_ENV = this.nodeEnv;
2028
+ else {
2029
+ if (this.viteNodeEnv === void 0) delete process.env.VITE_USER_NODE_ENV;
2030
+ else process.env.VITE_USER_NODE_ENV = this.viteNodeEnv;
2031
+ process.env.NODE_ENV = envFilesSetDevNodeEnv(mode, configDir) ? "development" : defaultMode;
2032
+ }
1997
2033
  return mode;
1998
2034
  }
1999
2035
  viteMode(defaultMode) {
@@ -2335,10 +2371,6 @@ const workerEntryConfig = () => ({ entrypoint: WORKER_ENTRY_ID });
2335
2371
  const BIND_ENV_ID = "virtual:seedcord/bind-env";
2336
2372
  const BUILT_FILES_ID = "virtual:seedcord/built-files";
2337
2373
  const BAKED_IDS_ID = "virtual:seedcord/baked-ids";
2338
- const BIND_ENV = `import { env } from 'cloudflare:workers';
2339
- import { Envapter, PortableSource } from 'envapt';
2340
- Envapter.useSource(new PortableSource(env));
2341
- `;
2342
2374
  const CWD_ID = "virtual:seedcord/cwd";
2343
2375
  function cwdSource(cwd) {
2344
2376
  return `process.cwd = () => ${JSON.stringify(cwd)};\n`;
@@ -2370,7 +2402,7 @@ function setupSources({ layout, folders, rootKey, mode }) {
2370
2402
  return new Map([
2371
2403
  [CWD_ID, cwdSource(cwd)],
2372
2404
  ...modules,
2373
- [BIND_ENV_ID, BIND_ENV],
2405
+ [BIND_ENV_ID, envBootstrapSource({ runtime: "worker" })],
2374
2406
  [BUILT_FILES_ID, builtFilesSource({
2375
2407
  layout,
2376
2408
  folders,
@@ -2542,13 +2574,13 @@ function scopesInCode(found, configuredGuilds) {
2542
2574
  }
2543
2575
  async function loadInstance({ projectLoader }, projectDir) {
2544
2576
  try {
2545
- var _usingCtx$5 = _usingCtx();
2546
- const project = _usingCtx$5.a(await openProjectWithSteps(quietSteps, projectLoader, { projectDir }));
2577
+ var _usingCtx$6 = _usingCtx();
2578
+ const project = _usingCtx$6.a(await openProjectWithSteps(quietSteps, projectLoader, { projectDir }));
2547
2579
  return await importInstance(project.modules, project.config.instance);
2548
2580
  } catch (_) {
2549
- _usingCtx$5.e = _;
2581
+ _usingCtx$6.e = _;
2550
2582
  } finally {
2551
- await _usingCtx$5.d();
2583
+ await _usingCtx$6.d();
2552
2584
  }
2553
2585
  }
2554
2586
  async function loadCodeScopes(steps, { projectLoader }, projectDir) {
@@ -2809,6 +2841,7 @@ function serverEntry(builtFiles, importBot) {
2809
2841
  rootExpression: ROOT_EXPRESSION,
2810
2842
  sourcePaths: false
2811
2843
  }),
2844
+ `await import('${ENV_BOOTSTRAP_ID}');`,
2812
2845
  ...importBot,
2813
2846
  ""
2814
2847
  ].join("\n");
@@ -2828,7 +2861,8 @@ function outputChunks(result) {
2828
2861
  function outputName(moduleId, layout) {
2829
2862
  if (isServerEntry(moduleId)) return ENTRY_FILE_NAME;
2830
2863
  if (moduleId && isListedFileId(moduleId)) return `_virtual/files${layout.listedKeyOf(listedFileOf(moduleId))}.js`;
2831
- return `[name]${BotLayout.builtExtension(withoutQuery(moduleId ?? ""))}`;
2864
+ if (moduleId && layout.holds(moduleId)) return BotLayout.builtPath(layout.keyOf(withoutQuery(moduleId))).slice(1);
2865
+ return "_virtual/[name]-[hash].js";
2832
2866
  }
2833
2867
  var ServerBuild = class extends TargetBuild {
2834
2868
  target;
@@ -2851,19 +2885,24 @@ var ServerBuild = class extends TargetBuild {
2851
2885
  rootKey: BotLayout.keyUnder(configDir, root),
2852
2886
  configFile: BotLayout.keyUnder(outDir, config.configFile)
2853
2887
  };
2854
- const result = await this.buildBot([serverEntry(builtFiles, importBot), pinModulePaths(layout)], {
2888
+ const fileName = (chunk) => outputName(chunk.facadeModuleId, layout);
2889
+ const result = await this.buildBot([
2890
+ envBootstrap({ runtime: "node" }),
2891
+ serverEntry(builtFiles, importBot),
2892
+ pinModulePaths(layout)
2893
+ ], {
2855
2894
  outDir,
2856
2895
  emptyOutDir: true,
2857
2896
  sourcemap: true,
2858
2897
  minify: false,
2859
2898
  target: NODE_TARGET,
2860
2899
  rolldownOptions: {
2861
- input: ENTRY_ID,
2900
+ input: [ENTRY_ID, ...await files.modulePaths()],
2901
+ preserveEntrySignatures: "strict",
2862
2902
  output: {
2863
2903
  format: "esm",
2864
- preserveModules: true,
2865
- preserveModulesRoot: root,
2866
- entryFileNames: (chunk) => outputName(chunk.facadeModuleId, layout)
2904
+ entryFileNames: fileName,
2905
+ chunkFileNames: fileName
2867
2906
  }
2868
2907
  }
2869
2908
  });
@@ -3054,13 +3093,13 @@ var BuildRunner = class BuildRunner {
3054
3093
  }
3055
3094
  async run(projectDir = process.cwd()) {
3056
3095
  try {
3057
- var _usingCtx$4 = _usingCtx();
3096
+ var _usingCtx$5 = _usingCtx();
3058
3097
  const { steps, typeChecker } = this.deps;
3059
3098
  const opened = await openProjectWithSteps(steps, this.deps.projectLoader, {
3060
3099
  projectDir,
3061
3100
  check: checkBuildTarget
3062
3101
  });
3063
- const build = _usingCtx$4.a(this.deps.buildFor(opened));
3102
+ const build = _usingCtx$5.a(this.deps.buildFor(opened));
3064
3103
  const { project } = build;
3065
3104
  const { config, modules } = project;
3066
3105
  printResolvedConfig(steps, config);
@@ -3080,9 +3119,9 @@ var BuildRunner = class BuildRunner {
3080
3119
  nextCommands: build.nextCommands(bundle)
3081
3120
  };
3082
3121
  } catch (_) {
3083
- _usingCtx$4.e = _;
3122
+ _usingCtx$5.e = _;
3084
3123
  } finally {
3085
- await _usingCtx$4.d();
3124
+ await _usingCtx$5.d();
3086
3125
  }
3087
3126
  }
3088
3127
  async bundle(build, instance) {
@@ -3357,9 +3396,9 @@ var CodegenRunner = class CodegenRunner {
3357
3396
  }
3358
3397
  async run(check) {
3359
3398
  try {
3360
- var _usingCtx$3 = _usingCtx();
3399
+ var _usingCtx$4 = _usingCtx();
3361
3400
  const { steps, projectLoader } = this.deps;
3362
- const { config, files, modules } = _usingCtx$3.a(await openProjectWithSteps(steps, projectLoader));
3401
+ const { config, files, modules } = _usingCtx$4.a(await openProjectWithSteps(steps, projectLoader));
3363
3402
  printResolvedConfig(steps, config);
3364
3403
  const instance = await steps.step("load bot", () => importInstance(modules, config.instance));
3365
3404
  return await this.generate({
@@ -3369,9 +3408,9 @@ var CodegenRunner = class CodegenRunner {
3369
3408
  modules
3370
3409
  }, check);
3371
3410
  } catch (_) {
3372
- _usingCtx$3.e = _;
3411
+ _usingCtx$4.e = _;
3373
3412
  } finally {
3374
- await _usingCtx$3.d();
3413
+ await _usingCtx$4.d();
3375
3414
  }
3376
3415
  }
3377
3416
  async writeFrom(bot) {
@@ -3433,12 +3472,6 @@ var CodegenCommand = class extends BaseCommand {
3433
3472
  }
3434
3473
  };
3435
3474
 
3436
- //#endregion
3437
- //#region src/core/interactive.ts
3438
- function isInteractive() {
3439
- return process.stdin.isTTY === true && process.stdout.isTTY === true && !process.env.CI;
3440
- }
3441
-
3442
3475
  //#endregion
3443
3476
  //#region src/core/output/stderrSteps.ts
3444
3477
  function stderrSteps(stdout = process.stdout, stderr = process.stderr) {
@@ -7159,10 +7192,6 @@ function installCliLogSinks(stack) {
7159
7192
  installNodeDefaults();
7160
7193
  stack.defer(() => LoggerChannelRegistry.instance.configure({}));
7161
7194
  }
7162
- function bindWorkerEnvToCli(workerEnv, stack) {
7163
- Envapter.useSource(merge(new FileSource(), new PortableSource(workerEnv.values())));
7164
- stack.defer(() => Envapter.useSource(new FileSource()));
7165
- }
7166
7195
  var EdgeDevRuntime = class extends BaseDevRuntime {
7167
7196
  target;
7168
7197
  settleStart;
@@ -7185,7 +7214,6 @@ var EdgeDevRuntime = class extends BaseDevRuntime {
7185
7214
  CloudflareWorker.load(this.target),
7186
7215
  WorkerEnv.load(this.target.cloudflareConfig, config.viteMode)
7187
7216
  ]);
7188
- bindWorkerEnvToCli(workerEnv, resources);
7189
7217
  const nodeCopy = await openModuleLoader(dirname(config.configFile), this.target, config.viteMode, config, {
7190
7218
  watch: devWatchOptions(files.layout),
7191
7219
  workerEnv
@@ -7295,11 +7323,20 @@ var ServerDevRuntime = class extends BaseDevRuntime {
7295
7323
  const hmr = this.openHmr(context, BOT_ENVIRONMENT, resources);
7296
7324
  const server = await openViteServer(resources, mergeViteConfig(serverViteConfig(context.config, context.files.layout), {
7297
7325
  mode: context.config.viteMode,
7298
- plugins: [hmr.plugin, context.config.vitePlugins.create()]
7326
+ plugins: [
7327
+ envBootstrap({
7328
+ runtime: "node",
7329
+ directory: dirname(context.config.configFile)
7330
+ }),
7331
+ hmr.plugin,
7332
+ context.config.vitePlugins.create()
7333
+ ]
7299
7334
  })).catch(rethrowVitePluginError);
7335
+ const modules = resources.use(new RunnerModuleLoader(createServerModuleRunner(botEnvironment(server.environments))));
7336
+ await modules.bindEnv();
7300
7337
  return {
7301
7338
  context,
7302
- modules: new RunnerModuleLoader(createServerModuleRunner(botEnvironment(server.environments))),
7339
+ modules,
7303
7340
  hmr,
7304
7341
  resources
7305
7342
  };
@@ -7749,13 +7786,13 @@ var DevRunner = class DevRunner {
7749
7786
  }
7750
7787
  async runSession() {
7751
7788
  try {
7752
- var _usingCtx$2 = _usingCtx();
7789
+ var _usingCtx$3 = _usingCtx();
7753
7790
  const { store, tunnel } = this.deps;
7754
7791
  resetChannelColors();
7755
7792
  store.setPhase("starting");
7756
7793
  store.setBusy(true);
7757
7794
  const restarts = this.restarts;
7758
- const { config, files } = _usingCtx$2.a(await this.deps.projectLoader.readConfig());
7795
+ const { config, files } = _usingCtx$3.a(await this.deps.projectLoader.readConfig());
7759
7796
  if (this.next !== "session" || this.restarts !== restarts) return;
7760
7797
  profileMark("config");
7761
7798
  store.setIdleAnimation(config.idleAnimation);
@@ -7771,9 +7808,9 @@ var DevRunner = class DevRunner {
7771
7808
  this.currentSession = null;
7772
7809
  }
7773
7810
  } catch (_) {
7774
- _usingCtx$2.e = _;
7811
+ _usingCtx$3.e = _;
7775
7812
  } finally {
7776
- await _usingCtx$2.d();
7813
+ await _usingCtx$3.d();
7777
7814
  }
7778
7815
  }
7779
7816
  async quit() {
@@ -7816,26 +7853,56 @@ var DevRunner = class DevRunner {
7816
7853
  //#endregion
7817
7854
  //#region src/commands/dev/runPlain.ts
7818
7855
  const logger = cliLogger("Dev");
7819
- async function runPlain(store, runner) {
7820
- let failure;
7821
- const answer = () => {
7822
- const { phase, commandUpdatePrompt, error } = store.getState();
7823
- if (commandUpdatePrompt !== null) runner.refreshCommands(true);
7824
- if (phase === "restart-required") {
7825
- logger.info("Restarting to pick up the change");
7826
- runner.restart();
7827
- } else if (phase === "error" && error !== null) {
7828
- failure ??= error;
7829
- runner.quit();
7830
- }
7831
- };
7832
- store.on("change", answer);
7856
+ const COMMANDS = /* @__PURE__ */ new Map([
7857
+ ["restart", (runner) => runner.restart()],
7858
+ ["disconnect", (runner) => runner.disconnect()],
7859
+ ["quit", (runner) => runner.quit()]
7860
+ ]);
7861
+ function commandOn(line) {
7833
7862
  try {
7834
- await runner.run();
7863
+ return COMMANDS.get(JSON.parse(line)?.do);
7864
+ } catch {
7865
+ return;
7866
+ }
7867
+ }
7868
+ function leaveToRun(command) {
7869
+ command.catch(() => void 0);
7870
+ }
7871
+ async function runPlain(store, runner, input) {
7872
+ try {
7873
+ var _usingCtx$2 = _usingCtx();
7874
+ let failure;
7875
+ const answer = () => {
7876
+ const { phase, commandUpdatePrompt, error } = store.getState();
7877
+ if (commandUpdatePrompt !== null) runner.refreshCommands(true);
7878
+ if (phase === "restart-required") {
7879
+ logger.info("Restarting to pick up the change");
7880
+ leaveToRun(runner.restart());
7881
+ } else if (phase === "error" && error !== null) {
7882
+ failure ??= error;
7883
+ leaveToRun(runner.quit());
7884
+ }
7885
+ };
7886
+ _usingCtx$2.u(createInterface({
7887
+ input,
7888
+ terminal: false
7889
+ })).on("line", (line) => {
7890
+ const command = commandOn(line);
7891
+ if (command) leaveToRun(command(runner));
7892
+ else logger.warn(`Ignoring stdin line: ${line}`);
7893
+ });
7894
+ store.on("change", answer);
7895
+ try {
7896
+ await runner.run();
7897
+ } finally {
7898
+ store.off("change", answer);
7899
+ }
7900
+ if (failure) throw failure;
7901
+ } catch (_) {
7902
+ _usingCtx$2.e = _;
7835
7903
  } finally {
7836
- store.off("change", answer);
7904
+ _usingCtx$2.d();
7837
7905
  }
7838
- if (failure) throw failure;
7839
7906
  }
7840
7907
 
7841
7908
  //#endregion
@@ -7855,7 +7922,7 @@ var DevCommand = class extends BaseCommand {
7855
7922
  try {
7856
7923
  var _usingCtx$1 = _usingCtx();
7857
7924
  _usingCtx$1.u(DevSignals.own(() => void runner.quit()));
7858
- await (isInteractive() ? this.runDevApp(store, runner, stateFolder) : runPlain(store, runner));
7925
+ await (isInteractive() ? this.runDevApp(store, runner, stateFolder) : runPlain(store, runner, process.stdin));
7859
7926
  } catch (_) {
7860
7927
  _usingCtx$1.e = _;
7861
7928
  } finally {