@walkeros/cli 0.3.4 → 0.3.6

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 (64) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +22 -0
  3. package/dist/__tests__/bundle/bundler.test.js +10 -14
  4. package/dist/__tests__/bundle/bundler.test.js.map +1 -1
  5. package/dist/__tests__/bundle/programmatic.test.js +5 -0
  6. package/dist/__tests__/bundle/programmatic.test.js.map +1 -1
  7. package/dist/__tests__/cli.test.js +4 -0
  8. package/dist/__tests__/cli.test.js.map +1 -1
  9. package/dist/__tests__/config-loader.test.js +3 -2
  10. package/dist/__tests__/config-loader.test.js.map +1 -1
  11. package/dist/commands/bundle/bundler.d.ts.map +1 -1
  12. package/dist/commands/bundle/bundler.js +3 -3
  13. package/dist/commands/bundle/bundler.js.map +1 -1
  14. package/dist/commands/bundle/index.d.ts.map +1 -1
  15. package/dist/commands/bundle/index.js +2 -2
  16. package/dist/commands/bundle/index.js.map +1 -1
  17. package/dist/commands/bundle/template-engine.d.ts +2 -0
  18. package/dist/commands/bundle/template-engine.d.ts.map +1 -1
  19. package/dist/commands/bundle/template-engine.js +5 -2
  20. package/dist/commands/bundle/template-engine.js.map +1 -1
  21. package/dist/commands/run/index.d.ts.map +1 -1
  22. package/dist/commands/run/index.js +8 -3
  23. package/dist/commands/run/index.js.map +1 -1
  24. package/dist/commands/run/types.d.ts +8 -4
  25. package/dist/commands/run/types.d.ts.map +1 -1
  26. package/dist/commands/run/validators.d.ts +1 -1
  27. package/dist/commands/run/validators.d.ts.map +1 -1
  28. package/dist/commands/run/validators.js +4 -3
  29. package/dist/commands/run/validators.js.map +1 -1
  30. package/dist/config/defaults.d.ts.map +1 -1
  31. package/dist/config/defaults.js +1 -4
  32. package/dist/config/defaults.js.map +1 -1
  33. package/dist/config/parser.d.ts.map +1 -1
  34. package/dist/config/parser.js +5 -0
  35. package/dist/config/parser.js.map +1 -1
  36. package/dist/config/utils.d.ts +34 -4
  37. package/dist/config/utils.d.ts.map +1 -1
  38. package/dist/config/utils.js +95 -7
  39. package/dist/config/utils.js.map +1 -1
  40. package/dist/core/asset-resolver.d.ts +41 -0
  41. package/dist/core/asset-resolver.d.ts.map +1 -0
  42. package/dist/core/asset-resolver.js +69 -0
  43. package/dist/core/asset-resolver.js.map +1 -0
  44. package/dist/core/docker.d.ts +8 -4
  45. package/dist/core/docker.d.ts.map +1 -1
  46. package/dist/core/docker.js +50 -15
  47. package/dist/core/docker.js.map +1 -1
  48. package/dist/core/index.d.ts +1 -0
  49. package/dist/core/index.d.ts.map +1 -1
  50. package/dist/core/index.js +1 -0
  51. package/dist/core/index.js.map +1 -1
  52. package/dist/index.d.ts +13 -6
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +217 -98
  55. package/dist/index.js.map +1 -1
  56. package/dist/types/bundle.d.ts +5 -2
  57. package/dist/types/bundle.d.ts.map +1 -1
  58. package/examples/README.md +330 -0
  59. package/examples/server-collect.json +53 -0
  60. package/examples/server-collect.mjs +13370 -0
  61. package/examples/web-serve.json +74 -0
  62. package/examples/web-serve.mjs +19456 -0
  63. package/package.json +5 -3
  64. /package/templates/{base.hbs → web.hbs} +0 -0
package/dist/index.js CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
-
6
- // src/commands/bundle/index.ts
7
- import path7 from "path";
5
+ import { readFileSync as readFileSync2 } from "fs";
6
+ import { fileURLToPath as fileURLToPath3 } from "url";
7
+ import { dirname, join } from "path";
8
8
 
9
9
  // src/core/logger.ts
10
10
  import chalk from "chalk";
@@ -123,14 +123,106 @@ function formatBytes(bytes) {
123
123
 
124
124
  // src/core/docker.ts
125
125
  import { spawn } from "child_process";
126
+ import path2 from "path";
127
+ import { readFileSync } from "fs";
128
+ import { fileURLToPath } from "url";
129
+ import { VERSION as DOCKER_VERSION } from "@walkeros/docker";
130
+
131
+ // src/config/utils.ts
132
+ import fs from "fs-extra";
126
133
  import path from "path";
127
- var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || "walkeros/cli:latest";
128
- var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || "walkeros/docker:latest";
134
+ import os from "os";
135
+ function isUrl(str) {
136
+ try {
137
+ const url = new URL(str);
138
+ return url.protocol === "http:" || url.protocol === "https:";
139
+ } catch {
140
+ return false;
141
+ }
142
+ }
143
+ async function downloadFromUrl(url) {
144
+ if (!isUrl(url)) {
145
+ throw new Error(`Invalid URL: ${url}`);
146
+ }
147
+ try {
148
+ const response = await fetch(url);
149
+ if (!response.ok) {
150
+ throw new Error(
151
+ `Failed to download ${url}: ${response.status} ${response.statusText}`
152
+ );
153
+ }
154
+ const content = await response.text();
155
+ const urlObj = new URL(url);
156
+ const urlFilename = path.basename(urlObj.pathname);
157
+ const extension = path.extname(urlFilename) || ".json";
158
+ const randomId = Math.random().toString(36).substring(2, 11);
159
+ const filename = `walkeros-download-${Date.now()}-${randomId}${extension}`;
160
+ const tempPath = path.join(os.tmpdir(), filename);
161
+ await fs.writeFile(tempPath, content, "utf-8");
162
+ return tempPath;
163
+ } catch (error) {
164
+ if (error instanceof Error) {
165
+ throw new Error(`Failed to download from URL: ${error.message}`);
166
+ }
167
+ throw error;
168
+ }
169
+ }
170
+ async function loadJsonConfig(configPath) {
171
+ let absolutePath;
172
+ let isTemporary = false;
173
+ if (isUrl(configPath)) {
174
+ absolutePath = await downloadFromUrl(configPath);
175
+ isTemporary = true;
176
+ } else {
177
+ absolutePath = path.resolve(configPath);
178
+ if (!await fs.pathExists(absolutePath)) {
179
+ throw new Error(`Configuration file not found: ${absolutePath}`);
180
+ }
181
+ }
182
+ try {
183
+ const rawConfig = await fs.readJson(absolutePath);
184
+ return rawConfig;
185
+ } catch (error) {
186
+ throw new Error(
187
+ `Invalid JSON in config file: ${configPath}. ${error instanceof Error ? error.message : error}`
188
+ );
189
+ } finally {
190
+ if (isTemporary) {
191
+ try {
192
+ await fs.remove(absolutePath);
193
+ } catch {
194
+ }
195
+ }
196
+ }
197
+ }
198
+ function getTempDir(tempDir = ".tmp") {
199
+ const randomId = Math.random().toString(36).substring(2, 11);
200
+ const basePath = path.isAbsolute(tempDir) ? tempDir : path.join(process.cwd(), tempDir);
201
+ return path.join(basePath, `cli-${Date.now()}-${randomId}`);
202
+ }
203
+
204
+ // src/core/docker.ts
205
+ function readPackageVersion() {
206
+ const moduleFilename = fileURLToPath(import.meta.url);
207
+ const moduleDir = path2.dirname(moduleFilename);
208
+ const prodPath = path2.join(moduleDir, "../package.json");
209
+ try {
210
+ const pkg = JSON.parse(readFileSync(prodPath, "utf-8"));
211
+ return pkg.version;
212
+ } catch {
213
+ const devPath = path2.join(moduleDir, "../../package.json");
214
+ const pkg = JSON.parse(readFileSync(devPath, "utf-8"));
215
+ return pkg.version;
216
+ }
217
+ }
218
+ var CLI_VERSION = readPackageVersion();
219
+ var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${CLI_VERSION}`;
220
+ var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
129
221
  function buildDockerCommand(command, args, options = {}, configFile) {
130
222
  const cwd = process.cwd();
131
223
  const cmd = ["docker", "run", "--rm"];
132
- if (configFile) {
133
- const configPath = path.resolve(cwd, configFile);
224
+ if (configFile && !isUrl(configFile)) {
225
+ const configPath = path2.resolve(cwd, configFile);
134
226
  cmd.push("-v", `${configPath}:/config/flow.json:ro`);
135
227
  args = args.map((arg) => arg === configFile ? "/config/flow.json" : arg);
136
228
  }
@@ -164,7 +256,7 @@ async function executeInDocker(command, args, options = {}, configFile) {
164
256
  options,
165
257
  configFile
166
258
  );
167
- return new Promise((resolve2, reject) => {
259
+ return new Promise((resolve, reject) => {
168
260
  const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
169
261
  stdio: options.silent ? "ignore" : "inherit",
170
262
  shell: false
@@ -174,7 +266,7 @@ async function executeInDocker(command, args, options = {}, configFile) {
174
266
  });
175
267
  proc.on("exit", (code) => {
176
268
  if (code === 0) {
177
- resolve2();
269
+ resolve();
178
270
  } else {
179
271
  reject(new Error(`Docker command exited with code ${code}`));
180
272
  }
@@ -182,12 +274,12 @@ async function executeInDocker(command, args, options = {}, configFile) {
182
274
  });
183
275
  }
184
276
  async function isDockerAvailable() {
185
- return new Promise((resolve2) => {
277
+ return new Promise((resolve) => {
186
278
  const proc = spawn("docker", ["--version"], {
187
279
  stdio: "ignore"
188
280
  });
189
- proc.on("error", () => resolve2(false));
190
- proc.on("exit", (code) => resolve2(code === 0));
281
+ proc.on("error", () => resolve(false));
282
+ proc.on("exit", (code) => resolve(code === 0));
191
283
  });
192
284
  }
193
285
  function buildDockerRunCommand(mode, flowPath, options = {}) {
@@ -195,21 +287,26 @@ function buildDockerRunCommand(mode, flowPath, options = {}) {
195
287
  const cmd = ["docker", "run", "--rm"];
196
288
  cmd.push("-e", `MODE=${mode}`);
197
289
  if (mode === "collect" && flowPath) {
198
- const absoluteFlowPath = path.resolve(cwd, flowPath);
290
+ const absoluteFlowPath = path2.resolve(cwd, flowPath);
199
291
  cmd.push("-v", `${absoluteFlowPath}:/app/flow.mjs:ro`);
200
292
  cmd.push("-e", "FLOW=/app/flow.mjs");
201
293
  }
202
- if (options.port !== void 0) {
203
- cmd.push("-p", `${options.port}:${options.port}`);
204
- cmd.push("-e", `PORT=${options.port}`);
294
+ if (mode === "serve" && flowPath) {
295
+ const absoluteFilePath = path2.resolve(cwd, flowPath);
296
+ cmd.push("-v", `${absoluteFilePath}:/app/bundle.mjs:ro`);
297
+ cmd.push("-e", "FILE_PATH=/app/bundle.mjs");
205
298
  }
299
+ const port = options.port !== void 0 ? options.port : 8080;
300
+ cmd.push("-p", `${port}:${port}`);
301
+ cmd.push("-e", `PORT=${port}`);
206
302
  if (options.host) {
207
303
  cmd.push("-e", `HOST=${options.host}`);
208
304
  }
209
- if (mode === "serve" && options.staticDir) {
210
- const absoluteStaticDir = path.resolve(cwd, options.staticDir);
211
- cmd.push("-v", `${absoluteStaticDir}:/app/dist:ro`);
212
- cmd.push("-e", "STATIC_DIR=/app/dist");
305
+ if (options.serveName) {
306
+ cmd.push("-e", `SERVE_NAME=${options.serveName}`);
307
+ }
308
+ if (options.servePath) {
309
+ cmd.push("-e", `SERVE_PATH=${options.servePath}`);
213
310
  }
214
311
  if (process.platform !== "win32") {
215
312
  try {
@@ -226,7 +323,7 @@ function buildDockerRunCommand(mode, flowPath, options = {}) {
226
323
  }
227
324
  async function executeRunInDocker(mode, flowPath, options = {}) {
228
325
  const dockerCmd = buildDockerRunCommand(mode, flowPath, options);
229
- return new Promise((resolve2, reject) => {
326
+ return new Promise((resolve, reject) => {
230
327
  const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
231
328
  stdio: options.silent ? "ignore" : "inherit",
232
329
  shell: false
@@ -236,7 +333,7 @@ async function executeRunInDocker(mode, flowPath, options = {}) {
236
333
  });
237
334
  proc.on("exit", (code) => {
238
335
  if (code === 0) {
239
- resolve2();
336
+ resolve();
240
337
  } else {
241
338
  reject(new Error(`Docker command exited with code ${code}`));
242
339
  }
@@ -283,6 +380,32 @@ async function executeCommand(localHandler, dockerCommand, dockerArgs, options,
283
380
  }
284
381
  }
285
382
 
383
+ // src/core/asset-resolver.ts
384
+ import { fileURLToPath as fileURLToPath2 } from "url";
385
+ import path3 from "path";
386
+ function getPackageRoot() {
387
+ const currentFile = fileURLToPath2(import.meta.url);
388
+ if (currentFile.includes("/src/")) {
389
+ const srcIndex = currentFile.indexOf("/src/");
390
+ return currentFile.substring(0, srcIndex);
391
+ }
392
+ return path3.resolve(currentFile, "../..");
393
+ }
394
+ function resolveAsset(assetPath, assetType, baseDir) {
395
+ const packageRoot = getPackageRoot();
396
+ if (!assetPath.includes("/") && !assetPath.includes("\\")) {
397
+ if (assetType === "template") {
398
+ return path3.join(packageRoot, "templates", assetPath);
399
+ }
400
+ return path3.join(packageRoot, "examples", assetPath);
401
+ }
402
+ if (path3.isAbsolute(assetPath)) {
403
+ return assetPath;
404
+ }
405
+ const resolveBase = baseDir || process.cwd();
406
+ return path3.resolve(resolveBase, assetPath);
407
+ }
408
+
286
409
  // src/config/validators.ts
287
410
  function isObject(value) {
288
411
  return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
@@ -297,29 +420,6 @@ function isSingleEnvConfig(data) {
297
420
  return isObject(data) && "flow" in data && "build" in data && isObject(data.flow) && isObject(data.build) && "platform" in data.flow && validatePlatform(data.flow.platform);
298
421
  }
299
422
 
300
- // src/config/utils.ts
301
- import fs from "fs-extra";
302
- import path2 from "path";
303
- async function loadJsonConfig(configPath) {
304
- const absolutePath = path2.resolve(configPath);
305
- if (!await fs.pathExists(absolutePath)) {
306
- throw new Error(`Configuration file not found: ${absolutePath}`);
307
- }
308
- try {
309
- const rawConfig = await fs.readJson(absolutePath);
310
- return rawConfig;
311
- } catch (error) {
312
- throw new Error(
313
- `Invalid JSON in config file: ${configPath}. ${error instanceof Error ? error.message : error}`
314
- );
315
- }
316
- }
317
- function getTempDir(tempDir = ".tmp") {
318
- const randomId = Math.random().toString(36).substring(2, 11);
319
- const basePath = path2.isAbsolute(tempDir) ? tempDir : path2.join(process.cwd(), tempDir);
320
- return path2.join(basePath, `cli-${Date.now()}-${randomId}`);
321
- }
322
-
323
423
  // src/config/defaults.ts
324
424
  function getDefaultBuildOptions(platform, code, output) {
325
425
  const common = {
@@ -353,23 +453,20 @@ function ensureBuildOptions(buildOptions, flowPlatform) {
353
453
  buildOptions.code || "",
354
454
  buildOptions.output
355
455
  );
356
- if (!buildOptions.code && !defaults.code) {
357
- throw new Error("BuildOptions.code is required");
358
- }
359
456
  if (!buildOptions.output && !defaults.output) {
360
457
  throw new Error("BuildOptions.output is required");
361
458
  }
362
459
  return {
363
460
  ...defaults,
364
461
  ...buildOptions,
365
- code: buildOptions.code || defaults.code,
462
+ code: buildOptions.code || defaults.code || "",
366
463
  output: buildOptions.output || defaults.output,
367
464
  packages: buildOptions.packages || defaults.packages
368
465
  };
369
466
  }
370
467
 
371
468
  // src/config/parser.ts
372
- import path3 from "path";
469
+ import path4 from "path";
373
470
  function parseBundleConfig(data) {
374
471
  if (!isObject(data)) {
375
472
  throw new Error(`Invalid config: expected object, got ${typeof data}`);
@@ -428,10 +525,13 @@ function normalizeConfigs(config, configPath) {
428
525
  ...buildDefaults,
429
526
  ...config.build
430
527
  };
431
- if (configPath && buildConfig.template && !path3.isAbsolute(buildConfig.template)) {
528
+ if (buildConfig.template === void 0) {
529
+ buildConfig.template = platform === "server" ? "server.hbs" : "web.hbs";
530
+ }
531
+ if (configPath && buildConfig.template && !path4.isAbsolute(buildConfig.template)) {
432
532
  if (buildConfig.template.startsWith("./") || buildConfig.template.startsWith("../")) {
433
- const configDir = path3.dirname(configPath);
434
- buildConfig.template = path3.resolve(configDir, buildConfig.template);
533
+ const configDir = path4.dirname(configPath);
534
+ buildConfig.template = path4.resolve(configDir, buildConfig.template);
435
535
  }
436
536
  }
437
537
  const buildOptions = ensureBuildOptions(buildConfig, platform);
@@ -538,15 +638,15 @@ import fs4 from "fs-extra";
538
638
 
539
639
  // src/commands/bundle/package-manager.ts
540
640
  import pacote from "pacote";
541
- import path4 from "path";
641
+ import path5 from "path";
542
642
  import fs2 from "fs-extra";
543
643
  function getPackageDirectory(baseDir, packageName, version) {
544
- return path4.join(baseDir, "node_modules", packageName);
644
+ return path5.join(baseDir, "node_modules", packageName);
545
645
  }
546
646
  function getCachedPackagePath(pkg, tempDir) {
547
- const cacheDir = path4.join(".tmp", "cache", "packages");
647
+ const cacheDir = path5.join(".tmp", "cache", "packages");
548
648
  const safeName = pkg.name.replace(/\//g, "-").replace(/@/g, "");
549
- return path4.join(cacheDir, `${safeName}-${pkg.version}`);
649
+ return path5.join(cacheDir, `${safeName}-${pkg.version}`);
550
650
  }
551
651
  async function isPackageCached(pkg, tempDir) {
552
652
  const cachedPath = getCachedPackagePath(pkg, tempDir);
@@ -584,12 +684,12 @@ async function resolveDependencies(pkg, packageDir, logger, visited = /* @__PURE
584
684
  }
585
685
  visited.add(pkgKey);
586
686
  try {
587
- const packageJsonPath = path4.join(packageDir, "package.json");
687
+ const packageJsonPath = path5.join(packageDir, "package.json");
588
688
  if (await fs2.pathExists(packageJsonPath)) {
589
- const packageJson = await fs2.readJson(packageJsonPath);
689
+ const packageJson2 = await fs2.readJson(packageJsonPath);
590
690
  const deps = {
591
- ...packageJson.dependencies,
592
- ...packageJson.peerDependencies
691
+ ...packageJson2.dependencies,
692
+ ...packageJson2.peerDependencies
593
693
  };
594
694
  for (const [name, versionSpec] of Object.entries(deps)) {
595
695
  if (typeof versionSpec === "string") {
@@ -621,7 +721,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
621
721
  if (useCache && await isPackageCached(pkg, targetDir)) {
622
722
  logger.debug(`Using cached ${packageSpec}...`);
623
723
  try {
624
- await fs2.ensureDir(path4.dirname(packageDir));
724
+ await fs2.ensureDir(path5.dirname(packageDir));
625
725
  await fs2.copy(cachedPath, packageDir);
626
726
  packagePaths.set(pkg.name, packageDir);
627
727
  const deps = await resolveDependencies(pkg, packageDir, logger);
@@ -640,8 +740,8 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
640
740
  }
641
741
  logger.debug(`Downloading ${packageSpec}...`);
642
742
  try {
643
- await fs2.ensureDir(path4.dirname(packageDir));
644
- const cacheDir = process.env.NPM_CACHE_DIR || path4.join(process.cwd(), ".npm-cache");
743
+ await fs2.ensureDir(path5.dirname(packageDir));
744
+ const cacheDir = process.env.NPM_CACHE_DIR || path5.join(process.cwd(), ".npm-cache");
645
745
  await pacote.extract(packageSpec, packageDir, {
646
746
  // Force npm registry download, prevent workspace resolution
647
747
  registry: "https://registry.npmjs.org",
@@ -654,7 +754,7 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
654
754
  });
655
755
  if (useCache) {
656
756
  try {
657
- await fs2.ensureDir(path4.dirname(cachedPath));
757
+ await fs2.ensureDir(path5.dirname(cachedPath));
658
758
  await fs2.copy(packageDir, cachedPath);
659
759
  logger.debug(`Cached ${packageSpec} for future use`);
660
760
  } catch (cacheError) {
@@ -678,7 +778,6 @@ async function downloadPackages(packages, targetDir, logger, useCache = true) {
678
778
 
679
779
  // src/commands/bundle/template-engine.ts
680
780
  import fs3 from "fs-extra";
681
- import path5 from "path";
682
781
  import Handlebars from "handlebars";
683
782
 
684
783
  // src/commands/bundle/serializer.ts
@@ -789,9 +888,11 @@ var TemplateEngine = class {
789
888
  }
790
889
  /**
791
890
  * Load template content from file path
891
+ *
892
+ * @param templatePath - Template path (bare name, relative, or absolute)
792
893
  */
793
894
  async loadTemplate(templatePath) {
794
- const resolvedPath = path5.resolve(templatePath);
895
+ const resolvedPath = resolveAsset(templatePath, "template");
795
896
  if (!await fs3.pathExists(resolvedPath)) {
796
897
  throw new Error(`Template file not found: ${resolvedPath}`);
797
898
  }
@@ -894,7 +995,10 @@ async function bundleCore(flowConfig, buildOptions, logger, showStats = false) {
894
995
  try {
895
996
  await esbuild.build(esbuildOptions);
896
997
  } catch (buildError) {
897
- throw createBuildError(buildError, buildOptions.code);
998
+ throw createBuildError(
999
+ buildError,
1000
+ buildOptions.code || ""
1001
+ );
898
1002
  }
899
1003
  logger.gray(`Output: ${outputPath}`);
900
1004
  let stats;
@@ -1110,8 +1214,8 @@ ${examplesMappings.join(",\n")}
1110
1214
  const flowWithProps = flowConfig;
1111
1215
  templatedCode = await templateEngine.process(
1112
1216
  buildOptions.template,
1113
- buildOptions.code,
1114
- // Pass user code as parameter
1217
+ buildOptions.code || "",
1218
+ // Pass user code as parameter (empty if undefined)
1115
1219
  flowWithProps.sources || {},
1116
1220
  flowWithProps.destinations || {},
1117
1221
  flowWithProps.collector || {},
@@ -1119,7 +1223,7 @@ ${examplesMappings.join(",\n")}
1119
1223
  // Pass build config to template
1120
1224
  );
1121
1225
  } else {
1122
- templatedCode = buildOptions.code;
1226
+ templatedCode = buildOptions.code || "";
1123
1227
  }
1124
1228
  let wrappedCode = templatedCode;
1125
1229
  const hasExport = /^\s*export\s/m.test(templatedCode);
@@ -1211,7 +1315,7 @@ async function bundleCommand(options) {
1211
1315
  throw new Error("Cannot use both --env and --all flags together");
1212
1316
  }
1213
1317
  logger.info("\u{1F4E6} Reading configuration...");
1214
- const configPath = path7.resolve(options.config);
1318
+ const configPath = options.config;
1215
1319
  const rawConfig = await loadJsonConfig(configPath);
1216
1320
  const configsToBundle = options.all ? loadAllEnvironments(rawConfig, { configPath, logger }) : [
1217
1321
  loadBundleConfig(rawConfig, {
@@ -1348,7 +1452,7 @@ async function bundle(configOrPath, options = {}) {
1348
1452
  }
1349
1453
 
1350
1454
  // src/commands/simulate/simulator.ts
1351
- import path8 from "path";
1455
+ import path7 from "path";
1352
1456
  import fs5 from "fs-extra";
1353
1457
 
1354
1458
  // src/commands/simulate/tracker.ts
@@ -1385,9 +1489,9 @@ var CallTracker = class {
1385
1489
  }
1386
1490
  for (const fullPath of paths) {
1387
1491
  const [destKey, ...pathParts] = fullPath.split(":");
1388
- const path10 = pathParts.join(":");
1389
- if (!path10) continue;
1390
- const cleanPath = path10.replace(/^call:/, "");
1492
+ const path9 = pathParts.join(":");
1493
+ if (!path9) continue;
1494
+ const cleanPath = path9.replace(/^call:/, "");
1391
1495
  const parts = cleanPath.split(".");
1392
1496
  let current = wrapped;
1393
1497
  let source = env;
@@ -1442,7 +1546,7 @@ async function simulateCore(configPath, event, options = {}) {
1442
1546
  try {
1443
1547
  logger.info("\u{1F3AF} Starting walkerOS simulation...");
1444
1548
  logger.info("\u{1F4E6} Loading bundle configuration...");
1445
- const fullConfigPath = path8.resolve(configPath);
1549
+ const fullConfigPath = path7.resolve(configPath);
1446
1550
  const rawConfig = await loadJsonConfig(fullConfigPath);
1447
1551
  parseBundleConfig(rawConfig);
1448
1552
  logger.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
@@ -1537,7 +1641,7 @@ ${envSetupCode.join("\n")}
1537
1641
 
1538
1642
  ${buildOptions.code || ""}
1539
1643
  `;
1540
- const tempOutput = path8.join(
1644
+ const tempOutput = path7.join(
1541
1645
  tempDir,
1542
1646
  `simulation-bundle-${generateId()}.mjs`
1543
1647
  );
@@ -1693,8 +1797,8 @@ async function simulate(configOrPath, event, options = {}) {
1693
1797
  }
1694
1798
 
1695
1799
  // src/commands/run/index.ts
1696
- import path9 from "path";
1697
- import os from "os";
1800
+ import path8 from "path";
1801
+ import os2 from "os";
1698
1802
  import {
1699
1803
  runFlow,
1700
1804
  runServeMode
@@ -1702,7 +1806,6 @@ import {
1702
1806
 
1703
1807
  // src/commands/run/validators.ts
1704
1808
  import { existsSync } from "fs";
1705
- import { resolve } from "path";
1706
1809
  var VALID_MODES = ["collect", "serve"];
1707
1810
  function validateMode(mode) {
1708
1811
  if (!VALID_MODES.includes(mode)) {
@@ -1714,7 +1817,7 @@ function validateMode(mode) {
1714
1817
  }
1715
1818
  }
1716
1819
  function validateFlowFile(filePath) {
1717
- const absolutePath = resolve(filePath);
1820
+ const absolutePath = resolveAsset(filePath, "bundle");
1718
1821
  if (!existsSync(absolutePath)) {
1719
1822
  throw new Error(
1720
1823
  `Flow file not found: ${filePath}
@@ -1753,17 +1856,17 @@ async function runCommand(mode, options) {
1753
1856
  let flowPath = null;
1754
1857
  if (mode === "collect") {
1755
1858
  if (isPreBuilt) {
1756
- flowPath = path9.resolve(configPath);
1859
+ flowPath = path8.resolve(configPath);
1757
1860
  if (!options.json && !options.silent) {
1758
- logger.info(`\u{1F4E6} Using pre-built flow: ${path9.basename(flowPath)}`);
1861
+ logger.info(`\u{1F4E6} Using pre-built flow: ${path8.basename(flowPath)}`);
1759
1862
  }
1760
1863
  } else {
1761
1864
  if (!options.json && !options.silent) {
1762
1865
  logger.info("\u{1F528} Building flow bundle...");
1763
1866
  }
1764
1867
  const rawConfig = await loadJsonConfig(configPath);
1765
- const tempPath = path9.join(
1766
- os.tmpdir(),
1868
+ const tempPath = path8.join(
1869
+ os2.tmpdir(),
1767
1870
  `walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
1768
1871
  );
1769
1872
  const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
@@ -1799,7 +1902,8 @@ async function runCommand(mode, options) {
1799
1902
  await executeRunInDocker(mode, flowPath, {
1800
1903
  port: options.port,
1801
1904
  host: options.host,
1802
- staticDir: options.staticDir,
1905
+ serveName: options.serveName,
1906
+ servePath: options.servePath,
1803
1907
  silent: options.silent
1804
1908
  });
1805
1909
  } else {
@@ -1823,7 +1927,9 @@ async function runCommand(mode, options) {
1823
1927
  const config = {
1824
1928
  port: options.port,
1825
1929
  host: options.host,
1826
- staticDir: options.staticDir
1930
+ serveName: options.serveName,
1931
+ servePath: options.servePath,
1932
+ filePath: flowPath || void 0
1827
1933
  };
1828
1934
  await runServeMode(config);
1829
1935
  break;
@@ -1866,11 +1972,11 @@ async function run(mode, options) {
1866
1972
  const isPreBuilt = flowFile.endsWith(".mjs") || flowFile.endsWith(".js") || flowFile.endsWith(".cjs");
1867
1973
  let flowPath;
1868
1974
  if (isPreBuilt) {
1869
- flowPath = path9.resolve(flowFile);
1975
+ flowPath = path8.resolve(flowFile);
1870
1976
  } else {
1871
1977
  const rawConfig = await loadJsonConfig(flowFile);
1872
- const tempPath = path9.join(
1873
- os.tmpdir(),
1978
+ const tempPath = path8.join(
1979
+ os2.tmpdir(),
1874
1980
  `walkeros-${Date.now()}-${Math.random().toString(36).slice(2, 9)}.mjs`
1875
1981
  );
1876
1982
  const existingBuild = typeof rawConfig === "object" && rawConfig !== null && "build" in rawConfig && typeof rawConfig.build === "object" ? rawConfig.build : {};
@@ -1901,7 +2007,9 @@ async function run(mode, options) {
1901
2007
  const config = {
1902
2008
  port: options.port,
1903
2009
  host: options.host,
1904
- staticDir: options.staticDir
2010
+ serveName: options.serveName,
2011
+ servePath: options.servePath,
2012
+ filePath: flowPath
1905
2013
  };
1906
2014
  await runServeMode(config);
1907
2015
  break;
@@ -1925,8 +2033,14 @@ async function run(mode, options) {
1925
2033
  }
1926
2034
 
1927
2035
  // src/index.ts
2036
+ var __filename = fileURLToPath3(import.meta.url);
2037
+ var __dirname = dirname(__filename);
2038
+ var packageJson = JSON.parse(
2039
+ readFileSync2(join(__dirname, "../package.json"), "utf-8")
2040
+ );
2041
+ var VERSION = packageJson.version;
1928
2042
  var program = new Command();
1929
- program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version("0.3.3");
2043
+ program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
1930
2044
  program.command("bundle [file]").description("Bundle NPM packages with custom code").option(
1931
2045
  "-e, --env <name>",
1932
2046
  "environment to build (for multi-environment configs)"
@@ -1956,9 +2070,11 @@ program.command("simulate [file]").description("Simulate event processing and ca
1956
2070
  });
1957
2071
  });
1958
2072
  var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
1959
- runCmd.command("collect <file>").description("Run collector mode (event collection endpoint)").option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
2073
+ runCmd.command("collect [file]").description(
2074
+ "Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
2075
+ ).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
1960
2076
  await runCommand("collect", {
1961
- config: file,
2077
+ config: file || "server-collect.mjs",
1962
2078
  port: options.port,
1963
2079
  host: options.host,
1964
2080
  json: options.json,
@@ -1968,12 +2084,15 @@ runCmd.command("collect <file>").description("Run collector mode (event collecti
1968
2084
  silent: options.silent
1969
2085
  });
1970
2086
  });
1971
- runCmd.command("serve <file>").description("Run serve mode (static file server for browser bundles)").option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--static-dir <dir>", "Static directory for serve mode").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
2087
+ runCmd.command("serve [file]").description(
2088
+ "Run serve mode (single-file server for browser bundles). Defaults to baked-in web-serve.mjs if no file specified."
2089
+ ).option("-p, --port <number>", "Port to listen on (default: 8080)", parseInt).option("-h, --host <address>", "Host address (default: 0.0.0.0)").option("--name <filename>", "Filename in URL (default: walker.js)").option("--path <directory>", "URL directory path (e.g., libs/v1)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--local", "execute in local Node.js instead of Docker").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
1972
2090
  await runCommand("serve", {
1973
- config: file,
2091
+ config: file || "web-serve.mjs",
1974
2092
  port: options.port,
1975
2093
  host: options.host,
1976
- staticDir: options.staticDir,
2094
+ serveName: options.name,
2095
+ servePath: options.path,
1977
2096
  json: options.json,
1978
2097
  verbose: options.verbose,
1979
2098
  local: options.local,