@walkeros/cli 0.7.0-next.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/CHANGELOG.md +8 -151
  2. package/README.md +123 -37
  3. package/dist/examples/flow-order-complete.json +0 -1
  4. package/dist/examples/flow-simple.json +0 -3
  5. package/dist/examples/flow.json +0 -1
  6. package/dist/index.d.ts +23 -13
  7. package/dist/index.js +882 -846
  8. package/dist/index.js.map +1 -1
  9. package/dist/runtime/main.d.ts +2 -0
  10. package/dist/runtime/main.js +271 -0
  11. package/dist/runtime/main.js.map +1 -0
  12. package/examples/flow-order-complete.json +0 -1
  13. package/examples/flow-simple.json +0 -3
  14. package/examples/flow.json +0 -1
  15. package/package.json +10 -7
  16. package/dist/__tests__/bundle/bundler-helpers.test.d.ts +0 -2
  17. package/dist/__tests__/bundle/bundler-helpers.test.d.ts.map +0 -1
  18. package/dist/__tests__/bundle/bundler-helpers.test.js +0 -151
  19. package/dist/__tests__/bundle/bundler-helpers.test.js.map +0 -1
  20. package/dist/__tests__/bundle/bundler.test.d.ts +0 -2
  21. package/dist/__tests__/bundle/bundler.test.d.ts.map +0 -1
  22. package/dist/__tests__/bundle/bundler.test.js +0 -353
  23. package/dist/__tests__/bundle/bundler.test.js.map +0 -1
  24. package/dist/__tests__/bundle/programmatic.test.d.ts +0 -2
  25. package/dist/__tests__/bundle/programmatic.test.d.ts.map +0 -1
  26. package/dist/__tests__/bundle/programmatic.test.js +0 -148
  27. package/dist/__tests__/bundle/programmatic.test.js.map +0 -1
  28. package/dist/__tests__/cli-e2e.test.d.ts +0 -8
  29. package/dist/__tests__/cli-e2e.test.d.ts.map +0 -1
  30. package/dist/__tests__/cli-e2e.test.js +0 -130
  31. package/dist/__tests__/cli-e2e.test.js.map +0 -1
  32. package/dist/__tests__/cli.test.d.ts +0 -2
  33. package/dist/__tests__/cli.test.d.ts.map +0 -1
  34. package/dist/__tests__/cli.test.js +0 -180
  35. package/dist/__tests__/cli.test.js.map +0 -1
  36. package/dist/__tests__/config-loader.test.d.ts +0 -7
  37. package/dist/__tests__/config-loader.test.d.ts.map +0 -1
  38. package/dist/__tests__/config-loader.test.js +0 -414
  39. package/dist/__tests__/config-loader.test.js.map +0 -1
  40. package/dist/__tests__/core/asset-resolver.test.d.ts +0 -2
  41. package/dist/__tests__/core/asset-resolver.test.d.ts.map +0 -1
  42. package/dist/__tests__/core/asset-resolver.test.js +0 -14
  43. package/dist/__tests__/core/asset-resolver.test.js.map +0 -1
  44. package/dist/__tests__/core/build-cache.test.d.ts +0 -2
  45. package/dist/__tests__/core/build-cache.test.d.ts.map +0 -1
  46. package/dist/__tests__/core/build-cache.test.js +0 -55
  47. package/dist/__tests__/core/build-cache.test.js.map +0 -1
  48. package/dist/__tests__/core/cache-utils.test.d.ts +0 -2
  49. package/dist/__tests__/core/cache-utils.test.d.ts.map +0 -1
  50. package/dist/__tests__/core/cache-utils.test.js +0 -70
  51. package/dist/__tests__/core/cache-utils.test.js.map +0 -1
  52. package/dist/__tests__/core/config.test.d.ts +0 -2
  53. package/dist/__tests__/core/config.test.d.ts.map +0 -1
  54. package/dist/__tests__/core/config.test.js +0 -72
  55. package/dist/__tests__/core/config.test.js.map +0 -1
  56. package/dist/__tests__/core/docker-url.test.d.ts +0 -2
  57. package/dist/__tests__/core/docker-url.test.d.ts.map +0 -1
  58. package/dist/__tests__/core/docker-url.test.js +0 -54
  59. package/dist/__tests__/core/docker-url.test.js.map +0 -1
  60. package/dist/__tests__/core/logger.test.d.ts +0 -2
  61. package/dist/__tests__/core/logger.test.d.ts.map +0 -1
  62. package/dist/__tests__/core/logger.test.js +0 -53
  63. package/dist/__tests__/core/logger.test.js.map +0 -1
  64. package/dist/__tests__/integration/bundle-run.integration.test.d.ts +0 -8
  65. package/dist/__tests__/integration/bundle-run.integration.test.d.ts.map +0 -1
  66. package/dist/__tests__/integration/bundle-run.integration.test.js +0 -54
  67. package/dist/__tests__/integration/bundle-run.integration.test.js.map +0 -1
  68. package/dist/__tests__/push/push.test.d.ts +0 -7
  69. package/dist/__tests__/push/push.test.d.ts.map +0 -1
  70. package/dist/__tests__/push/push.test.js +0 -197
  71. package/dist/__tests__/push/push.test.js.map +0 -1
  72. package/dist/__tests__/simulate/env-loader.test.d.ts +0 -2
  73. package/dist/__tests__/simulate/env-loader.test.d.ts.map +0 -1
  74. package/dist/__tests__/simulate/env-loader.test.js +0 -47
  75. package/dist/__tests__/simulate/env-loader.test.js.map +0 -1
  76. package/dist/__tests__/simulate/node-executor.test.d.ts +0 -5
  77. package/dist/__tests__/simulate/node-executor.test.d.ts.map +0 -1
  78. package/dist/__tests__/simulate/node-executor.test.js +0 -25
  79. package/dist/__tests__/simulate/node-executor.test.js.map +0 -1
  80. package/dist/__tests__/simulate/server-simulate.integration.test.d.ts +0 -5
  81. package/dist/__tests__/simulate/server-simulate.integration.test.d.ts.map +0 -1
  82. package/dist/__tests__/simulate/server-simulate.integration.test.js +0 -58
  83. package/dist/__tests__/simulate/server-simulate.integration.test.js.map +0 -1
  84. package/dist/__tests__/smoke/production.smoke.test.d.ts +0 -8
  85. package/dist/__tests__/smoke/production.smoke.test.d.ts.map +0 -1
  86. package/dist/__tests__/smoke/production.smoke.test.js +0 -65
  87. package/dist/__tests__/smoke/production.smoke.test.js.map +0 -1
  88. package/dist/commands/bundle/bundler.d.ts +0 -32
  89. package/dist/commands/bundle/bundler.d.ts.map +0 -1
  90. package/dist/commands/bundle/bundler.js +0 -583
  91. package/dist/commands/bundle/bundler.js.map +0 -1
  92. package/dist/commands/bundle/index.d.ts +0 -57
  93. package/dist/commands/bundle/index.d.ts.map +0 -1
  94. package/dist/commands/bundle/index.js +0 -200
  95. package/dist/commands/bundle/index.js.map +0 -1
  96. package/dist/commands/bundle/package-manager.d.ts +0 -8
  97. package/dist/commands/bundle/package-manager.d.ts.map +0 -1
  98. package/dist/commands/bundle/package-manager.js +0 -197
  99. package/dist/commands/bundle/package-manager.js.map +0 -1
  100. package/dist/commands/bundle/stats.d.ts +0 -23
  101. package/dist/commands/bundle/stats.d.ts.map +0 -1
  102. package/dist/commands/bundle/stats.js +0 -52
  103. package/dist/commands/bundle/stats.js.map +0 -1
  104. package/dist/commands/cache.d.ts +0 -3
  105. package/dist/commands/cache.d.ts.map +0 -1
  106. package/dist/commands/cache.js +0 -44
  107. package/dist/commands/cache.js.map +0 -1
  108. package/dist/commands/push/index.d.ts +0 -7
  109. package/dist/commands/push/index.d.ts.map +0 -1
  110. package/dist/commands/push/index.js +0 -257
  111. package/dist/commands/push/index.js.map +0 -1
  112. package/dist/commands/push/types.d.ts +0 -21
  113. package/dist/commands/push/types.d.ts.map +0 -1
  114. package/dist/commands/push/types.js +0 -2
  115. package/dist/commands/push/types.js.map +0 -1
  116. package/dist/commands/run/__tests__/run.integration.test.d.ts +0 -8
  117. package/dist/commands/run/__tests__/run.integration.test.d.ts.map +0 -1
  118. package/dist/commands/run/__tests__/run.integration.test.js +0 -52
  119. package/dist/commands/run/__tests__/run.integration.test.js.map +0 -1
  120. package/dist/commands/run/__tests__/validators.test.d.ts +0 -2
  121. package/dist/commands/run/__tests__/validators.test.d.ts.map +0 -1
  122. package/dist/commands/run/__tests__/validators.test.js +0 -80
  123. package/dist/commands/run/__tests__/validators.test.js.map +0 -1
  124. package/dist/commands/run/execution.d.ts +0 -14
  125. package/dist/commands/run/execution.d.ts.map +0 -1
  126. package/dist/commands/run/execution.js +0 -41
  127. package/dist/commands/run/execution.js.map +0 -1
  128. package/dist/commands/run/index.d.ts +0 -39
  129. package/dist/commands/run/index.d.ts.map +0 -1
  130. package/dist/commands/run/index.js +0 -191
  131. package/dist/commands/run/index.js.map +0 -1
  132. package/dist/commands/run/types.d.ts +0 -60
  133. package/dist/commands/run/types.d.ts.map +0 -1
  134. package/dist/commands/run/types.js +0 -7
  135. package/dist/commands/run/types.js.map +0 -1
  136. package/dist/commands/run/utils.d.ts +0 -29
  137. package/dist/commands/run/utils.d.ts.map +0 -1
  138. package/dist/commands/run/utils.js +0 -52
  139. package/dist/commands/run/utils.js.map +0 -1
  140. package/dist/commands/run/validators.d.ts +0 -33
  141. package/dist/commands/run/validators.d.ts.map +0 -1
  142. package/dist/commands/run/validators.js +0 -58
  143. package/dist/commands/run/validators.js.map +0 -1
  144. package/dist/commands/simulate/env-loader.d.ts +0 -19
  145. package/dist/commands/simulate/env-loader.d.ts.map +0 -1
  146. package/dist/commands/simulate/env-loader.js +0 -46
  147. package/dist/commands/simulate/env-loader.js.map +0 -1
  148. package/dist/commands/simulate/index.d.ts +0 -48
  149. package/dist/commands/simulate/index.d.ts.map +0 -1
  150. package/dist/commands/simulate/index.js +0 -116
  151. package/dist/commands/simulate/index.js.map +0 -1
  152. package/dist/commands/simulate/jsdom-executor.d.ts +0 -37
  153. package/dist/commands/simulate/jsdom-executor.d.ts.map +0 -1
  154. package/dist/commands/simulate/jsdom-executor.js +0 -137
  155. package/dist/commands/simulate/jsdom-executor.js.map +0 -1
  156. package/dist/commands/simulate/node-executor.d.ts +0 -28
  157. package/dist/commands/simulate/node-executor.d.ts.map +0 -1
  158. package/dist/commands/simulate/node-executor.js +0 -94
  159. package/dist/commands/simulate/node-executor.js.map +0 -1
  160. package/dist/commands/simulate/simulator.d.ts +0 -14
  161. package/dist/commands/simulate/simulator.d.ts.map +0 -1
  162. package/dist/commands/simulate/simulator.js +0 -162
  163. package/dist/commands/simulate/simulator.js.map +0 -1
  164. package/dist/commands/simulate/tracker.d.ts +0 -30
  165. package/dist/commands/simulate/tracker.d.ts.map +0 -1
  166. package/dist/commands/simulate/tracker.js +0 -96
  167. package/dist/commands/simulate/tracker.js.map +0 -1
  168. package/dist/commands/simulate/types.d.ts +0 -18
  169. package/dist/commands/simulate/types.d.ts.map +0 -1
  170. package/dist/commands/simulate/types.js +0 -2
  171. package/dist/commands/simulate/types.js.map +0 -1
  172. package/dist/config/build-defaults.d.ts +0 -49
  173. package/dist/config/build-defaults.d.ts.map +0 -1
  174. package/dist/config/build-defaults.js +0 -70
  175. package/dist/config/build-defaults.js.map +0 -1
  176. package/dist/config/index.d.ts +0 -13
  177. package/dist/config/index.d.ts.map +0 -1
  178. package/dist/config/index.js +0 -15
  179. package/dist/config/index.js.map +0 -1
  180. package/dist/config/loader.d.ts +0 -81
  181. package/dist/config/loader.d.ts.map +0 -1
  182. package/dist/config/loader.js +0 -155
  183. package/dist/config/loader.js.map +0 -1
  184. package/dist/config/utils.d.ts +0 -114
  185. package/dist/config/utils.d.ts.map +0 -1
  186. package/dist/config/utils.js +0 -257
  187. package/dist/config/utils.js.map +0 -1
  188. package/dist/config/validators.d.ts +0 -52
  189. package/dist/config/validators.d.ts.map +0 -1
  190. package/dist/config/validators.js +0 -85
  191. package/dist/config/validators.js.map +0 -1
  192. package/dist/core/asset-resolver.d.ts +0 -34
  193. package/dist/core/asset-resolver.d.ts.map +0 -1
  194. package/dist/core/asset-resolver.js +0 -70
  195. package/dist/core/asset-resolver.js.map +0 -1
  196. package/dist/core/build-cache.d.ts +0 -23
  197. package/dist/core/build-cache.d.ts.map +0 -1
  198. package/dist/core/build-cache.js +0 -43
  199. package/dist/core/build-cache.js.map +0 -1
  200. package/dist/core/cache-utils.d.ts +0 -27
  201. package/dist/core/cache-utils.d.ts.map +0 -1
  202. package/dist/core/cache-utils.js +0 -60
  203. package/dist/core/cache-utils.js.map +0 -1
  204. package/dist/core/docker.d.ts +0 -102
  205. package/dist/core/docker.d.ts.map +0 -1
  206. package/dist/core/docker.js +0 -278
  207. package/dist/core/docker.js.map +0 -1
  208. package/dist/core/execution.d.ts +0 -34
  209. package/dist/core/execution.d.ts.map +0 -1
  210. package/dist/core/execution.js +0 -64
  211. package/dist/core/execution.js.map +0 -1
  212. package/dist/core/index.d.ts +0 -10
  213. package/dist/core/index.d.ts.map +0 -1
  214. package/dist/core/index.js +0 -10
  215. package/dist/core/index.js.map +0 -1
  216. package/dist/core/local-packages.d.ts +0 -19
  217. package/dist/core/local-packages.d.ts.map +0 -1
  218. package/dist/core/local-packages.js +0 -60
  219. package/dist/core/local-packages.js.map +0 -1
  220. package/dist/core/logger.d.ts +0 -28
  221. package/dist/core/logger.d.ts.map +0 -1
  222. package/dist/core/logger.js +0 -88
  223. package/dist/core/logger.js.map +0 -1
  224. package/dist/core/output.d.ts +0 -30
  225. package/dist/core/output.d.ts.map +0 -1
  226. package/dist/core/output.js +0 -46
  227. package/dist/core/output.js.map +0 -1
  228. package/dist/core/temp-manager.d.ts +0 -51
  229. package/dist/core/temp-manager.d.ts.map +0 -1
  230. package/dist/core/temp-manager.js +0 -73
  231. package/dist/core/temp-manager.js.map +0 -1
  232. package/dist/core/timer.d.ts +0 -14
  233. package/dist/core/timer.d.ts.map +0 -1
  234. package/dist/core/timer.js +0 -29
  235. package/dist/core/timer.js.map +0 -1
  236. package/dist/core/utils.d.ts +0 -10
  237. package/dist/core/utils.d.ts.map +0 -1
  238. package/dist/core/utils.js +0 -12
  239. package/dist/core/utils.js.map +0 -1
  240. package/dist/index.d.ts.map +0 -1
  241. package/dist/schemas/index.d.ts +0 -9
  242. package/dist/schemas/index.d.ts.map +0 -1
  243. package/dist/schemas/index.js +0 -9
  244. package/dist/schemas/index.js.map +0 -1
  245. package/dist/schemas/primitives.d.ts +0 -37
  246. package/dist/schemas/primitives.d.ts.map +0 -1
  247. package/dist/schemas/primitives.js +0 -43
  248. package/dist/schemas/primitives.js.map +0 -1
  249. package/dist/schemas/run.d.ts +0 -23
  250. package/dist/schemas/run.d.ts.map +0 -1
  251. package/dist/schemas/run.js +0 -20
  252. package/dist/schemas/run.js.map +0 -1
  253. package/dist/types/bundle.d.ts +0 -141
  254. package/dist/types/bundle.d.ts.map +0 -1
  255. package/dist/types/bundle.js +0 -10
  256. package/dist/types/bundle.js.map +0 -1
  257. package/dist/types/global.d.ts +0 -51
  258. package/dist/types/global.d.ts.map +0 -1
  259. package/dist/types/global.js +0 -30
  260. package/dist/types/global.js.map +0 -1
  261. package/dist/types/index.d.ts +0 -8
  262. package/dist/types/index.d.ts.map +0 -1
  263. package/dist/types/index.js +0 -8
  264. package/dist/types/index.js.map +0 -1
  265. package/dist/version.d.ts +0 -3
  266. package/dist/version.d.ts.map +0 -1
  267. package/dist/version.js +0 -27
  268. package/dist/version.js.map +0 -1
  269. package/dist/walker.js +0 -1
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import { VERSION as DOCKER_VERSION2 } from "@walkeros/docker";
5
+ import chalk2 from "chalk";
6
6
 
7
7
  // src/version.ts
8
8
  import { readFileSync } from "fs";
@@ -29,74 +29,74 @@ var VERSION = JSON.parse(findPackageJson()).version;
29
29
 
30
30
  // src/commands/bundle/index.ts
31
31
  import path9 from "path";
32
+ import fs8 from "fs-extra";
32
33
 
33
34
  // src/core/logger.ts
34
35
  import chalk from "chalk";
36
+ var BRAND_COLOR = "#01b5e2";
35
37
  function createLogger(options = {}) {
36
38
  const { verbose = false, silent = false, json = false } = options;
37
39
  const shouldLog = !silent && !json;
38
40
  const shouldDebug = verbose && !silent && !json;
39
41
  return {
40
- log: (color, ...args) => {
42
+ log: (...args) => {
41
43
  if (shouldLog) {
42
44
  const message = args.map((arg) => String(arg)).join(" ");
43
- const colorMap = {
44
- red: chalk.red,
45
- green: chalk.green,
46
- blue: chalk.blue,
47
- yellow: chalk.yellow,
48
- gray: chalk.gray,
49
- grey: chalk.gray,
50
- cyan: chalk.cyan,
51
- magenta: chalk.magenta,
52
- white: chalk.white,
53
- black: chalk.black
54
- };
55
- const colorFn = colorMap[color];
56
- const coloredMessage = colorFn ? colorFn(message) : message;
57
- console.log(coloredMessage);
45
+ console.log(message);
58
46
  }
59
47
  },
60
- info: (...args) => {
48
+ brand: (...args) => {
61
49
  if (shouldLog) {
62
50
  const message = args.map((arg) => String(arg)).join(" ");
63
- console.log(chalk.blue(message));
51
+ console.log(chalk.hex(BRAND_COLOR)(message));
64
52
  }
65
53
  },
66
- success: (...args) => {
67
- if (shouldLog) {
54
+ error: (...args) => {
55
+ if (!json) {
68
56
  const message = args.map((arg) => String(arg)).join(" ");
69
- console.log(chalk.green(message));
57
+ console.error(chalk.red(message));
70
58
  }
71
59
  },
72
- warning: (...args) => {
60
+ debug: (...args) => {
61
+ if (shouldDebug) {
62
+ const message = args.map((arg) => String(arg)).join(" ");
63
+ console.log(` ${message}`);
64
+ }
65
+ },
66
+ json: (data) => {
67
+ if (!silent) {
68
+ console.log(JSON.stringify(data, null, 2));
69
+ }
70
+ },
71
+ // Backward-compatible methods (all use default terminal color per design)
72
+ info: (...args) => {
73
73
  if (shouldLog) {
74
74
  const message = args.map((arg) => String(arg)).join(" ");
75
- console.log(chalk.yellow(message));
75
+ console.log(message);
76
76
  }
77
77
  },
78
- warn: (...args) => {
78
+ success: (...args) => {
79
79
  if (shouldLog) {
80
80
  const message = args.map((arg) => String(arg)).join(" ");
81
- console.log(chalk.yellow(message));
81
+ console.log(message);
82
82
  }
83
83
  },
84
- error: (...args) => {
85
- if (!json) {
84
+ warning: (...args) => {
85
+ if (shouldLog) {
86
86
  const message = args.map((arg) => String(arg)).join(" ");
87
- console.error(chalk.red(message));
87
+ console.log(message);
88
88
  }
89
89
  },
90
- debug: (...args) => {
91
- if (shouldDebug) {
90
+ warn: (...args) => {
91
+ if (shouldLog) {
92
92
  const message = args.map((arg) => String(arg)).join(" ");
93
- console.log(chalk.gray(message));
93
+ console.log(message);
94
94
  }
95
95
  },
96
96
  gray: (...args) => {
97
97
  if (shouldLog) {
98
98
  const message = args.map((arg) => String(arg)).join(" ");
99
- console.log(chalk.gray(message));
99
+ console.log(message);
100
100
  }
101
101
  }
102
102
  };
@@ -109,6 +109,23 @@ function createCommandLogger(options) {
109
109
  });
110
110
  }
111
111
 
112
+ // src/core/collector-logger.ts
113
+ function createCollectorLoggerConfig(cliLogger, verbose) {
114
+ return {
115
+ level: verbose ? "DEBUG" : "ERROR",
116
+ handler: (level, message, context, scope) => {
117
+ const scopePath = scope.length > 0 ? `[${scope.join(":")}] ` : "";
118
+ const hasContext = Object.keys(context).length > 0;
119
+ const contextStr = hasContext ? ` ${JSON.stringify(context)}` : "";
120
+ if (level === 0) {
121
+ cliLogger.error(`${scopePath}${message}${contextStr}`);
122
+ } else if (verbose) {
123
+ cliLogger.debug(`${scopePath}${message}${contextStr}`);
124
+ }
125
+ }
126
+ };
127
+ }
128
+
112
129
  // src/core/timer.ts
113
130
  function createTimer() {
114
131
  let startTime = 0;
@@ -152,16 +169,26 @@ function formatBytes(bytes) {
152
169
  return (bytes / 1024).toFixed(2);
153
170
  }
154
171
 
155
- // src/core/docker.ts
156
- import { spawn } from "child_process";
157
- import path2 from "path";
158
- import fs2 from "fs-extra";
159
- import { VERSION as DOCKER_VERSION } from "@walkeros/docker";
172
+ // src/core/tmp.ts
173
+ import path from "path";
174
+ var DEFAULT_TMP_ROOT = ".tmp";
175
+ function getTmpPath(tmpDir, ...segments) {
176
+ const root = tmpDir || DEFAULT_TMP_ROOT;
177
+ const absoluteRoot = path.isAbsolute(root) ? root : path.resolve(root);
178
+ return path.join(absoluteRoot, ...segments);
179
+ }
180
+ function getDefaultTmpRoot() {
181
+ return DEFAULT_TMP_ROOT;
182
+ }
183
+
184
+ // src/core/asset-resolver.ts
185
+ import { fileURLToPath as fileURLToPath2 } from "url";
186
+ import { existsSync } from "fs";
187
+ import path3 from "path";
160
188
 
161
189
  // src/config/utils.ts
162
190
  import fs from "fs-extra";
163
- import path from "path";
164
- import os from "os";
191
+ import path2 from "path";
165
192
  function isUrl(str) {
166
193
  try {
167
194
  const url = new URL(str);
@@ -182,12 +209,9 @@ async function downloadFromUrl(url) {
182
209
  );
183
210
  }
184
211
  const content = await response.text();
185
- const urlObj = new URL(url);
186
- const urlFilename = path.basename(urlObj.pathname);
187
- const extension = path.extname(urlFilename) || ".json";
188
- const randomId = Math.random().toString(36).substring(2, 11);
189
- const filename = `walkeros-download-${Date.now()}-${randomId}${extension}`;
190
- const tempPath = path.join(os.tmpdir(), filename);
212
+ const downloadsDir = getTmpPath(void 0, "downloads");
213
+ await fs.ensureDir(downloadsDir);
214
+ const tempPath = path2.join(downloadsDir, "flow.json");
191
215
  await fs.writeFile(tempPath, content, "utf-8");
192
216
  return tempPath;
193
217
  } catch (error) {
@@ -204,7 +228,7 @@ async function loadJsonConfig(configPath) {
204
228
  absolutePath = await downloadFromUrl(configPath);
205
229
  isTemporary = true;
206
230
  } else {
207
- absolutePath = path.resolve(configPath);
231
+ absolutePath = path2.resolve(configPath);
208
232
  if (!await fs.pathExists(absolutePath)) {
209
233
  throw new Error(`Configuration file not found: ${absolutePath}`);
210
234
  }
@@ -225,11 +249,6 @@ async function loadJsonConfig(configPath) {
225
249
  }
226
250
  }
227
251
  }
228
- function getTempDir(tempDir = ".tmp") {
229
- const randomId = Math.random().toString(36).substring(2, 11);
230
- const basePath = path.isAbsolute(tempDir) ? tempDir : path.join(process.cwd(), tempDir);
231
- return path.join(basePath, `cli-${Date.now()}-${randomId}`);
232
- }
233
252
  async function loadJsonFromSource(source, options) {
234
253
  const paramName = options?.name || "input";
235
254
  if (!source || source.trim() === "") {
@@ -260,7 +279,7 @@ async function loadJsonFromSource(source, options) {
260
279
  );
261
280
  }
262
281
  }
263
- const resolvedPath = path.resolve(trimmedSource);
282
+ const resolvedPath = path2.resolve(trimmedSource);
264
283
  if (await fs.pathExists(resolvedPath)) {
265
284
  try {
266
285
  const data = await fs.readJson(resolvedPath);
@@ -284,203 +303,7 @@ async function loadJsonFromSource(source, options) {
284
303
  }
285
304
  }
286
305
 
287
- // src/core/docker.ts
288
- var CLI_DOCKER_IMAGE = process.env.WALKEROS_CLI_DOCKER_IMAGE || `walkeros/cli:${VERSION}`;
289
- var RUNTIME_DOCKER_IMAGE = process.env.WALKEROS_RUNTIME_DOCKER_IMAGE || `walkeros/docker:${DOCKER_VERSION}`;
290
- function buildCommonDockerArgs(options) {
291
- const args = [options.config];
292
- if (options.json) args.push("--json");
293
- if (options.verbose) args.push("--verbose");
294
- if (options.silent) args.push("--silent");
295
- return args;
296
- }
297
- function buildDockerCommand(command, args, options = {}, configFile) {
298
- const cwd = process.cwd();
299
- const cmd = ["docker", "run", "--rm"];
300
- if (configFile && !isUrl(configFile)) {
301
- const configPath = path2.resolve(cwd, configFile);
302
- cmd.push("-v", `${configPath}:/config/flow.json:ro`);
303
- args = args.map((arg) => arg === configFile ? "/config/flow.json" : arg);
304
- }
305
- cmd.push("-v", `${cwd}:/workspace`);
306
- cmd.push("-w", "/workspace");
307
- if (process.platform !== "win32") {
308
- try {
309
- const uid = process.getuid?.();
310
- const gid = process.getgid?.();
311
- if (uid !== void 0 && gid !== void 0) {
312
- cmd.push("--user", `${uid}:${gid}`);
313
- }
314
- } catch {
315
- }
316
- }
317
- if (options.verbose) {
318
- cmd.push("-e", "VERBOSE=true");
319
- }
320
- if (options.silent) {
321
- cmd.push("-e", "SILENT=true");
322
- }
323
- cmd.push(CLI_DOCKER_IMAGE);
324
- cmd.push(command, ...args);
325
- return cmd;
326
- }
327
- async function executeInDocker(command, args, options = {}, configFile) {
328
- let tempFile;
329
- let effectiveConfigFile = configFile;
330
- try {
331
- if (configFile && isUrl(configFile)) {
332
- tempFile = await downloadFromUrl(configFile);
333
- effectiveConfigFile = tempFile;
334
- }
335
- const containerArgs = [...args, "--local"];
336
- const dockerCmd = buildDockerCommand(
337
- command,
338
- containerArgs,
339
- options,
340
- effectiveConfigFile
341
- );
342
- return await new Promise((resolve, reject) => {
343
- const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
344
- stdio: options.silent ? "ignore" : "inherit",
345
- shell: false
346
- });
347
- proc.on("error", (error) => {
348
- reject(new Error(`Docker execution failed: ${error.message}`));
349
- });
350
- proc.on("exit", (code) => {
351
- if (code === 0) {
352
- resolve();
353
- } else {
354
- process.exit(code || 1);
355
- }
356
- });
357
- });
358
- } finally {
359
- if (tempFile) {
360
- try {
361
- await fs2.remove(tempFile);
362
- } catch {
363
- }
364
- }
365
- }
366
- }
367
- async function isDockerAvailable() {
368
- return new Promise((resolve) => {
369
- const proc = spawn("docker", ["--version"], {
370
- stdio: "ignore"
371
- });
372
- proc.on("error", () => resolve(false));
373
- proc.on("exit", (code) => resolve(code === 0));
374
- });
375
- }
376
- function buildDockerRunCommand(mode, flowPath, options = {}) {
377
- const cwd = process.cwd();
378
- const cmd = ["docker", "run", "--rm"];
379
- cmd.push("-e", `MODE=${mode}`);
380
- if (mode === "collect" && flowPath) {
381
- const absoluteFlowPath = path2.resolve(cwd, flowPath);
382
- const flowDir = path2.dirname(absoluteFlowPath);
383
- const flowFile = path2.basename(absoluteFlowPath);
384
- cmd.push("-v", `${flowDir}:/app/dist:ro`);
385
- cmd.push("-e", `FLOW=/app/dist/${flowFile}`);
386
- }
387
- if (mode === "serve" && flowPath) {
388
- const absoluteFilePath = path2.resolve(cwd, flowPath);
389
- cmd.push("-v", `${absoluteFilePath}:/app/bundle.mjs:ro`);
390
- cmd.push("-e", "FILE_PATH=/app/bundle.mjs");
391
- }
392
- const port = options.port !== void 0 ? options.port : 8080;
393
- cmd.push("-p", `${port}:${port}`);
394
- cmd.push("-e", `PORT=${port}`);
395
- if (options.host) {
396
- cmd.push("-e", `HOST=${options.host}`);
397
- }
398
- if (options.serveName) {
399
- cmd.push("-e", `SERVE_NAME=${options.serveName}`);
400
- }
401
- if (options.servePath) {
402
- cmd.push("-e", `SERVE_PATH=${options.servePath}`);
403
- }
404
- if (process.platform !== "win32") {
405
- try {
406
- const uid = process.getuid?.();
407
- const gid = process.getgid?.();
408
- if (uid !== void 0 && gid !== void 0) {
409
- cmd.push("--user", `${uid}:${gid}`);
410
- }
411
- } catch {
412
- }
413
- }
414
- cmd.push(RUNTIME_DOCKER_IMAGE);
415
- return cmd;
416
- }
417
- async function executeRunInDocker(mode, flowPath, options = {}) {
418
- const dockerCmd = buildDockerRunCommand(mode, flowPath, options);
419
- return new Promise((resolve, reject) => {
420
- const proc = spawn(dockerCmd[0], dockerCmd.slice(1), {
421
- stdio: options.silent ? "ignore" : "inherit",
422
- shell: false
423
- });
424
- proc.on("error", (error) => {
425
- reject(new Error(`Docker execution failed: ${error.message}`));
426
- });
427
- proc.on("exit", (code) => {
428
- if (code === 0) {
429
- resolve();
430
- } else {
431
- process.exit(code || 1);
432
- }
433
- });
434
- });
435
- }
436
-
437
- // src/core/execution.ts
438
- function getExecutionMode(options) {
439
- if (options.local || process.env.WALKEROS_CONTAINER === "true") {
440
- return "local";
441
- }
442
- return "docker";
443
- }
444
- async function executeCommand(localHandler, dockerCommand, dockerArgs, options, logger2, configFile) {
445
- const mode = getExecutionMode(options);
446
- if (options.dryRun) {
447
- if (mode === "docker") {
448
- const cmd = `docker run walkeros/cli:latest ${dockerCommand} ${dockerArgs.join(" ")}`;
449
- logger2?.info(`[DRY-RUN] Would execute: ${cmd}`);
450
- } else {
451
- logger2?.info(
452
- `[DRY-RUN] Would execute locally: ${dockerCommand} ${dockerArgs.join(" ")}`
453
- );
454
- }
455
- return;
456
- }
457
- if (mode === "local") {
458
- if (logger2 && !options.silent) {
459
- logger2.info("\u{1F5A5}\uFE0F Executing locally...");
460
- }
461
- await localHandler();
462
- } else {
463
- const dockerAvailable = await isDockerAvailable();
464
- if (!dockerAvailable) {
465
- throw new Error(
466
- "Docker is not available. Please install Docker or use --local flag to execute locally."
467
- );
468
- }
469
- if (logger2 && !options.silent) {
470
- logger2.info("\u{1F433} Executing in Docker container...");
471
- }
472
- await executeInDocker(dockerCommand, dockerArgs, options, configFile);
473
- }
474
- }
475
-
476
- // src/core/temp-manager.ts
477
- import { getHashServer } from "@walkeros/server-core";
478
- import fs3 from "fs-extra";
479
-
480
306
  // src/core/asset-resolver.ts
481
- import { fileURLToPath as fileURLToPath2 } from "url";
482
- import { existsSync } from "fs";
483
- import path3 from "path";
484
307
  var cachedAssetDir;
485
308
  function getAssetDir() {
486
309
  if (cachedAssetDir) return cachedAssetDir;
@@ -517,22 +340,22 @@ function getErrorMessage(error) {
517
340
 
518
341
  // src/core/local-packages.ts
519
342
  import path4 from "path";
520
- import fs4 from "fs-extra";
343
+ import fs2 from "fs-extra";
521
344
  async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
522
345
  const absolutePath = path4.isAbsolute(localPath) ? localPath : path4.resolve(configDir, localPath);
523
- if (!await fs4.pathExists(absolutePath)) {
346
+ if (!await fs2.pathExists(absolutePath)) {
524
347
  throw new Error(
525
348
  `Local package path not found: ${localPath} (resolved to ${absolutePath})`
526
349
  );
527
350
  }
528
351
  const pkgJsonPath = path4.join(absolutePath, "package.json");
529
- if (!await fs4.pathExists(pkgJsonPath)) {
352
+ if (!await fs2.pathExists(pkgJsonPath)) {
530
353
  throw new Error(
531
354
  `No package.json found at ${absolutePath}. Is this a valid package directory?`
532
355
  );
533
356
  }
534
357
  const distPath = path4.join(absolutePath, "dist");
535
- const hasDistFolder = await fs4.pathExists(distPath);
358
+ const hasDistFolder = await fs2.pathExists(distPath);
536
359
  if (!hasDistFolder) {
537
360
  logger2.warn(
538
361
  `\u26A0\uFE0F ${packageName}: No dist/ folder found. Using package root.`
@@ -547,18 +370,18 @@ async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
547
370
  }
548
371
  async function copyLocalPackage(localPkg, targetDir, logger2) {
549
372
  const packageDir = path4.join(targetDir, "node_modules", localPkg.name);
550
- await fs4.ensureDir(path4.dirname(packageDir));
551
- await fs4.copy(
373
+ await fs2.ensureDir(path4.dirname(packageDir));
374
+ await fs2.copy(
552
375
  path4.join(localPkg.absolutePath, "package.json"),
553
376
  path4.join(packageDir, "package.json")
554
377
  );
555
378
  if (localPkg.hasDistFolder) {
556
- await fs4.copy(localPkg.distPath, path4.join(packageDir, "dist"));
379
+ await fs2.copy(localPkg.distPath, path4.join(packageDir, "dist"));
557
380
  } else {
558
- const entries = await fs4.readdir(localPkg.absolutePath);
381
+ const entries = await fs2.readdir(localPkg.absolutePath);
559
382
  for (const entry of entries) {
560
383
  if (!["node_modules", ".turbo", ".git"].includes(entry)) {
561
- await fs4.copy(
384
+ await fs2.copy(
562
385
  path4.join(localPkg.absolutePath, entry),
563
386
  path4.join(packageDir, entry)
564
387
  );
@@ -569,6 +392,33 @@ async function copyLocalPackage(localPkg, targetDir, logger2) {
569
392
  return packageDir;
570
393
  }
571
394
 
395
+ // src/core/input-detector.ts
396
+ import fs3 from "fs-extra";
397
+ async function detectInput(inputPath, platformOverride) {
398
+ const content = await loadContent(inputPath);
399
+ try {
400
+ JSON.parse(content);
401
+ return { type: "config", content };
402
+ } catch {
403
+ const platform = platformOverride ?? detectPlatformFromPath(inputPath);
404
+ return { type: "bundle", content, platform };
405
+ }
406
+ }
407
+ function detectPlatformFromPath(inputPath) {
408
+ const cleanPath = inputPath.split("?")[0];
409
+ return cleanPath.endsWith(".mjs") ? "server" : "web";
410
+ }
411
+ async function loadContent(inputPath) {
412
+ if (isUrl(inputPath)) {
413
+ const response = await fetch(inputPath);
414
+ if (!response.ok) {
415
+ throw new Error(`Failed to fetch ${inputPath}: ${response.status}`);
416
+ }
417
+ return response.text();
418
+ }
419
+ return fs3.readFile(inputPath, "utf8");
420
+ }
421
+
572
422
  // src/config/validators.ts
573
423
  import { schemas } from "@walkeros/core/dev";
574
424
  var { safeParseSetup } = schemas;
@@ -579,8 +429,8 @@ function validateFlowSetup(data) {
579
429
  const result = safeParseSetup(data);
580
430
  if (!result.success) {
581
431
  const errors = result.error.issues.map((issue) => {
582
- const path15 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
583
- return ` - ${path15}: ${issue.message}`;
432
+ const path14 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
433
+ return ` - ${path14}: ${issue.message}`;
584
434
  }).join("\n");
585
435
  throw new Error(`Invalid configuration:
586
436
  ${errors}`);
@@ -599,7 +449,6 @@ var WEB_BUILD_DEFAULTS = {
599
449
  minify: true,
600
450
  sourcemap: false,
601
451
  cache: true,
602
- tempDir: ".tmp",
603
452
  windowCollector: "collector",
604
453
  windowElb: "elb"
605
454
  };
@@ -609,8 +458,7 @@ var SERVER_BUILD_DEFAULTS = {
609
458
  target: "node20",
610
459
  minify: true,
611
460
  sourcemap: false,
612
- cache: true,
613
- tempDir: ".tmp"
461
+ cache: true
614
462
  };
615
463
  var DEFAULT_OUTPUT_PATHS = {
616
464
  web: "./dist/walker.js",
@@ -625,7 +473,7 @@ function getDefaultOutput(platform) {
625
473
 
626
474
  // src/config/loader.ts
627
475
  import path5 from "path";
628
- import fs5 from "fs-extra";
476
+ import fs4 from "fs-extra";
629
477
  import { getFlowConfig, getPlatform } from "@walkeros/core";
630
478
  var DEFAULT_INCLUDE_FOLDER = "./shared";
631
479
  function loadBundleConfig(rawConfig, options) {
@@ -641,18 +489,12 @@ function loadBundleConfig(rawConfig, options) {
641
489
  }
642
490
  const buildDefaults = getBuildDefaults(platform);
643
491
  const packages = flowConfig.packages || {};
644
- let output = getDefaultOutput(platform);
645
- if (options.buildOverrides?.output) {
646
- output = options.buildOverrides.output;
647
- }
648
- const configDir = path5.dirname(options.configPath);
649
- if (!path5.isAbsolute(output)) {
650
- output = path5.resolve(configDir, output);
651
- }
492
+ const output = options.buildOverrides?.output || getDefaultOutput(platform);
493
+ const configDir = isUrl(options.configPath) ? process.cwd() : path5.dirname(options.configPath);
652
494
  let includes = setup.include;
653
495
  if (!includes) {
654
496
  const defaultIncludePath = path5.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
655
- if (fs5.pathExistsSync(defaultIncludePath)) {
497
+ if (fs4.pathExistsSync(defaultIncludePath)) {
656
498
  includes = [DEFAULT_INCLUDE_FOLDER];
657
499
  }
658
500
  }
@@ -711,20 +553,24 @@ function loadAllFlows(rawConfig, options) {
711
553
  })
712
554
  );
713
555
  }
556
+ async function loadFlowConfig(configPath, options) {
557
+ const rawConfig = await loadJsonConfig(configPath);
558
+ return loadBundleConfig(rawConfig, { configPath, ...options });
559
+ }
714
560
 
715
561
  // src/commands/bundle/bundler.ts
716
562
  import esbuild from "esbuild";
717
563
  import path8 from "path";
718
- import fs8 from "fs-extra";
564
+ import fs7 from "fs-extra";
719
565
  import { packageNameToVariable } from "@walkeros/core";
720
566
 
721
567
  // src/commands/bundle/package-manager.ts
722
568
  import pacote from "pacote";
723
569
  import path6 from "path";
724
- import fs6 from "fs-extra";
570
+ import fs5 from "fs-extra";
725
571
 
726
572
  // src/core/cache-utils.ts
727
- import { getHashServer as getHashServer2 } from "@walkeros/server-core";
573
+ import { getHashServer } from "@walkeros/server-core";
728
574
  var HASH_LENGTH = 12;
729
575
  function isMutableVersion(version) {
730
576
  return version === "latest" || version.includes("^") || version.includes("~") || version.includes("*") || version.includes("x");
@@ -737,10 +583,10 @@ async function getPackageCacheKey(packageName, version, date) {
737
583
  if (isMutableVersion(version)) {
738
584
  const dateStr = date ?? getTodayDate();
739
585
  const input2 = `${safeName}@${version}:${dateStr}`;
740
- return getHashServer2(input2, HASH_LENGTH);
586
+ return getHashServer(input2, HASH_LENGTH);
741
587
  }
742
588
  const input = `${safeName}@${version}`;
743
- return getHashServer2(input, HASH_LENGTH);
589
+ return getHashServer(input, HASH_LENGTH);
744
590
  }
745
591
  function normalizeJson(content) {
746
592
  const parsed = JSON.parse(content);
@@ -750,21 +596,28 @@ async function getFlowConfigCacheKey(content, date) {
750
596
  const dateStr = date ?? getTodayDate();
751
597
  const normalized = normalizeJson(content);
752
598
  const input = `${normalized}:${dateStr}`;
753
- return getHashServer2(input, HASH_LENGTH);
599
+ return getHashServer(input, HASH_LENGTH);
754
600
  }
755
601
 
756
602
  // src/commands/bundle/package-manager.ts
603
+ var PACKAGE_DOWNLOAD_TIMEOUT_MS = 6e4;
604
+ async function withTimeout(promise, ms, errorMessage) {
605
+ const timeout = new Promise(
606
+ (_, reject) => setTimeout(() => reject(new Error(errorMessage)), ms)
607
+ );
608
+ return Promise.race([promise, timeout]);
609
+ }
757
610
  function getPackageDirectory(baseDir, packageName, version) {
758
611
  return path6.join(baseDir, "node_modules", packageName);
759
612
  }
760
- async function getCachedPackagePath(pkg, tempDir) {
761
- const cacheDir = path6.join(".tmp", "cache", "packages");
613
+ async function getCachedPackagePath(pkg, tmpDir) {
614
+ const cacheDir = getTmpPath(tmpDir, "cache", "packages");
762
615
  const cacheKey = await getPackageCacheKey(pkg.name, pkg.version);
763
616
  return path6.join(cacheDir, cacheKey);
764
617
  }
765
- async function isPackageCached(pkg, tempDir) {
766
- const cachedPath = await getCachedPackagePath(pkg, tempDir);
767
- return fs6.pathExists(cachedPath);
618
+ async function isPackageCached(pkg, tmpDir) {
619
+ const cachedPath = await getCachedPackagePath(pkg, tmpDir);
620
+ return fs5.pathExists(cachedPath);
768
621
  }
769
622
  function validateNoDuplicatePackages(packages) {
770
623
  const packageMap = /* @__PURE__ */ new Map();
@@ -799,8 +652,8 @@ async function resolveDependencies(pkg, packageDir, logger2, visited = /* @__PUR
799
652
  visited.add(pkgKey);
800
653
  try {
801
654
  const packageJsonPath = path6.join(packageDir, "package.json");
802
- if (await fs6.pathExists(packageJsonPath)) {
803
- const packageJson = await fs6.readJson(packageJsonPath);
655
+ if (await fs5.pathExists(packageJsonPath)) {
656
+ const packageJson = await fs5.readJson(packageJsonPath);
804
657
  const deps = {
805
658
  ...packageJson.dependencies,
806
659
  ...packageJson.peerDependencies
@@ -820,6 +673,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
820
673
  const packagePaths = /* @__PURE__ */ new Map();
821
674
  const downloadQueue = [...packages];
822
675
  const processed = /* @__PURE__ */ new Set();
676
+ const userSpecifiedPackages = new Set(packages.map((p) => p.name));
823
677
  const localPackageMap = /* @__PURE__ */ new Map();
824
678
  for (const pkg of packages) {
825
679
  if (pkg.path) {
@@ -827,7 +681,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
827
681
  }
828
682
  }
829
683
  validateNoDuplicatePackages(packages);
830
- await fs6.ensureDir(targetDir);
684
+ await fs5.ensureDir(targetDir);
831
685
  while (downloadQueue.length > 0) {
832
686
  const pkg = downloadQueue.shift();
833
687
  const pkgKey = `${pkg.name}@${pkg.version}`;
@@ -858,12 +712,14 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
858
712
  }
859
713
  const packageSpec = `${pkg.name}@${pkg.version}`;
860
714
  const packageDir = getPackageDirectory(targetDir, pkg.name, pkg.version);
861
- const cachedPath = await getCachedPackagePath(pkg, targetDir);
862
- if (useCache && await isPackageCached(pkg, targetDir)) {
863
- logger2.debug(`Using cached ${packageSpec}...`);
715
+ const cachedPath = await getCachedPackagePath(pkg);
716
+ if (useCache && await isPackageCached(pkg)) {
717
+ if (userSpecifiedPackages.has(pkg.name)) {
718
+ logger2.debug(`Downloading ${packageSpec} (cached)`);
719
+ }
864
720
  try {
865
- await fs6.ensureDir(path6.dirname(packageDir));
866
- await fs6.copy(cachedPath, packageDir);
721
+ await fs5.ensureDir(path6.dirname(packageDir));
722
+ await fs5.copy(cachedPath, packageDir);
867
723
  packagePaths.set(pkg.name, packageDir);
868
724
  const deps = await resolveDependencies(pkg, packageDir, logger2);
869
725
  for (const dep of deps) {
@@ -879,27 +735,34 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
879
735
  );
880
736
  }
881
737
  }
882
- logger2.debug(`Downloading ${packageSpec}...`);
883
738
  try {
884
- await fs6.ensureDir(path6.dirname(packageDir));
885
- const cacheDir = process.env.NPM_CACHE_DIR || path6.join(process.cwd(), ".npm-cache");
886
- await pacote.extract(packageSpec, packageDir, {
887
- // Force npm registry download, prevent workspace resolution
888
- registry: "https://registry.npmjs.org",
889
- // Force online fetching from registry (don't use cached workspace packages)
890
- preferOnline: true,
891
- // Cache for performance
892
- cache: cacheDir,
893
- // Don't resolve relative to workspace context
894
- where: void 0
895
- });
739
+ await fs5.ensureDir(path6.dirname(packageDir));
740
+ const cacheDir = process.env.NPM_CACHE_DIR || getTmpPath(void 0, "cache", "npm");
741
+ await withTimeout(
742
+ pacote.extract(packageSpec, packageDir, {
743
+ // Force npm registry download, prevent workspace resolution
744
+ registry: "https://registry.npmjs.org",
745
+ // Force online fetching from registry (don't use cached workspace packages)
746
+ preferOnline: true,
747
+ // Cache for performance
748
+ cache: cacheDir,
749
+ // Don't resolve relative to workspace context
750
+ where: void 0
751
+ }),
752
+ PACKAGE_DOWNLOAD_TIMEOUT_MS,
753
+ `Package download timed out after ${PACKAGE_DOWNLOAD_TIMEOUT_MS / 1e3}s: ${packageSpec}`
754
+ );
755
+ if (userSpecifiedPackages.has(pkg.name)) {
756
+ const pkgStats = await fs5.stat(path6.join(packageDir, "package.json"));
757
+ const pkgJsonSize = pkgStats.size;
758
+ const sizeKB = (pkgJsonSize / 1024).toFixed(1);
759
+ logger2.debug(`Downloading ${packageSpec} (${sizeKB} KB)`);
760
+ }
896
761
  if (useCache) {
897
762
  try {
898
- await fs6.ensureDir(path6.dirname(cachedPath));
899
- await fs6.copy(packageDir, cachedPath);
900
- logger2.debug(`Cached ${packageSpec} for future use`);
763
+ await fs5.ensureDir(path6.dirname(cachedPath));
764
+ await fs5.copy(packageDir, cachedPath);
901
765
  } catch (cacheError) {
902
- logger2.debug(`Failed to cache ${packageSpec}: ${cacheError}`);
903
766
  }
904
767
  }
905
768
  packagePaths.set(pkg.name, packageDir);
@@ -918,26 +781,26 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
918
781
  }
919
782
 
920
783
  // src/core/build-cache.ts
921
- import fs7 from "fs-extra";
784
+ import fs6 from "fs-extra";
922
785
  import path7 from "path";
923
- var BUILD_CACHE_DIR = path7.join(".tmp", "cache", "builds");
924
- async function getBuildCachePath(configContent, cacheDir = BUILD_CACHE_DIR) {
786
+ async function getBuildCachePath(configContent, tmpDir) {
787
+ const cacheDir = getTmpPath(tmpDir, "cache", "builds");
925
788
  const cacheKey = await getFlowConfigCacheKey(configContent);
926
789
  return path7.join(cacheDir, `${cacheKey}.js`);
927
790
  }
928
- async function isBuildCached(configContent, cacheDir = BUILD_CACHE_DIR) {
929
- const cachePath = await getBuildCachePath(configContent, cacheDir);
930
- return fs7.pathExists(cachePath);
791
+ async function isBuildCached(configContent, tmpDir) {
792
+ const cachePath = await getBuildCachePath(configContent, tmpDir);
793
+ return fs6.pathExists(cachePath);
931
794
  }
932
- async function cacheBuild(configContent, buildOutput, cacheDir = BUILD_CACHE_DIR) {
933
- const cachePath = await getBuildCachePath(configContent, cacheDir);
934
- await fs7.ensureDir(path7.dirname(cachePath));
935
- await fs7.writeFile(cachePath, buildOutput, "utf-8");
795
+ async function cacheBuild(configContent, buildOutput, tmpDir) {
796
+ const cachePath = await getBuildCachePath(configContent, tmpDir);
797
+ await fs6.ensureDir(path7.dirname(cachePath));
798
+ await fs6.writeFile(cachePath, buildOutput, "utf-8");
936
799
  }
937
- async function getCachedBuild(configContent, cacheDir = BUILD_CACHE_DIR) {
938
- const cachePath = await getBuildCachePath(configContent, cacheDir);
939
- if (await fs7.pathExists(cachePath)) {
940
- return await fs7.readFile(cachePath, "utf-8");
800
+ async function getCachedBuild(configContent, tmpDir) {
801
+ const cachePath = await getBuildCachePath(configContent, tmpDir);
802
+ if (await fs6.pathExists(cachePath)) {
803
+ return await fs6.readFile(cachePath, "utf-8");
941
804
  }
942
805
  return null;
943
806
  }
@@ -948,8 +811,8 @@ async function copyIncludes(includes, sourceDir, outputDir, logger2) {
948
811
  const sourcePath = path8.resolve(sourceDir, include);
949
812
  const folderName = path8.basename(include);
950
813
  const destPath = path8.join(outputDir, folderName);
951
- if (await fs8.pathExists(sourcePath)) {
952
- await fs8.copy(sourcePath, destPath);
814
+ if (await fs7.pathExists(sourcePath)) {
815
+ await fs7.copy(sourcePath, destPath);
953
816
  logger2.debug(`Copied ${include} to output`);
954
817
  } else {
955
818
  logger2.debug(`Include folder not found: ${include}`);
@@ -970,21 +833,22 @@ function generateCacheKeyContent(flowConfig, buildOptions) {
970
833
  }
971
834
  async function bundleCore(flowConfig, buildOptions, logger2, showStats = false) {
972
835
  const bundleStartTime = Date.now();
973
- const TEMP_DIR = buildOptions.tempDir ? path8.isAbsolute(buildOptions.tempDir) ? buildOptions.tempDir : path8.resolve(buildOptions.tempDir) : getTempDir();
836
+ const TEMP_DIR = buildOptions.tempDir || getTmpPath();
974
837
  if (buildOptions.cache !== false) {
975
838
  const configContent = generateCacheKeyContent(flowConfig, buildOptions);
976
839
  const cached = await isBuildCached(configContent);
977
840
  if (cached) {
978
841
  const cachedBuild = await getCachedBuild(configContent);
979
842
  if (cachedBuild) {
980
- logger2.info("\u2728 Using cached build");
843
+ logger2.debug("Using cached build");
981
844
  const outputPath = path8.resolve(buildOptions.output);
982
- await fs8.ensureDir(path8.dirname(outputPath));
983
- await fs8.writeFile(outputPath, cachedBuild);
984
- logger2.gray(`Output: ${outputPath}`);
985
- logger2.success("\u2705 Build completed (from cache)");
845
+ await fs7.ensureDir(path8.dirname(outputPath));
846
+ await fs7.writeFile(outputPath, cachedBuild);
847
+ const stats = await fs7.stat(outputPath);
848
+ const sizeKB = (stats.size / 1024).toFixed(1);
849
+ logger2.log(`Output: ${outputPath} (${sizeKB} KB, cached)`);
986
850
  if (showStats) {
987
- const stats = await fs8.stat(outputPath);
851
+ const stats2 = await fs7.stat(outputPath);
988
852
  const packageStats = Object.entries(buildOptions.packages).map(
989
853
  ([name, pkg]) => ({
990
854
  name: `${name}@${pkg.version || "latest"}`,
@@ -993,7 +857,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
993
857
  })
994
858
  );
995
859
  return {
996
- totalSize: stats.size,
860
+ totalSize: stats2.size,
997
861
  packages: packageStats,
998
862
  buildTime: Date.now() - bundleStartTime,
999
863
  treeshakingEffective: true
@@ -1004,11 +868,8 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1004
868
  }
1005
869
  }
1006
870
  try {
1007
- if (!buildOptions.tempDir) {
1008
- await fs8.emptyDir(TEMP_DIR);
1009
- }
1010
- logger2.debug("Cleaned temporary directory");
1011
- logger2.info("\u{1F4E5} Downloading packages...");
871
+ await fs7.ensureDir(TEMP_DIR);
872
+ logger2.debug("Downloading packages");
1012
873
  const packagesArray = Object.entries(buildOptions.packages).map(
1013
874
  ([name, packageConfig]) => ({
1014
875
  name,
@@ -1028,7 +889,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1028
889
  for (const [pkgName, pkgPath] of packagePaths.entries()) {
1029
890
  if (pkgName.startsWith("@walkeros/")) {
1030
891
  const pkgJsonPath = path8.join(pkgPath, "package.json");
1031
- const pkgJson = await fs8.readJSON(pkgJsonPath);
892
+ const pkgJson = await fs7.readJSON(pkgJsonPath);
1032
893
  if (!pkgJson.exports && pkgJson.module) {
1033
894
  pkgJson.exports = {
1034
895
  ".": {
@@ -1036,26 +897,28 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1036
897
  require: pkgJson.main
1037
898
  }
1038
899
  };
1039
- await fs8.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
900
+ await fs7.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
1040
901
  }
1041
902
  }
1042
903
  }
1043
904
  const packageJsonPath = path8.join(TEMP_DIR, "package.json");
1044
- await fs8.writeFile(
905
+ await fs7.writeFile(
1045
906
  packageJsonPath,
1046
907
  JSON.stringify({ type: "module" }, null, 2)
1047
908
  );
1048
- logger2.info("\u{1F4DD} Creating entry point...");
909
+ logger2.debug("Creating entry point");
1049
910
  const entryContent = await createEntryPoint(
1050
911
  flowConfig,
1051
912
  buildOptions,
1052
913
  packagePaths
1053
914
  );
1054
915
  const entryPath = path8.join(TEMP_DIR, "entry.js");
1055
- await fs8.writeFile(entryPath, entryContent);
1056
- logger2.info("\u26A1 Bundling with esbuild...");
916
+ await fs7.writeFile(entryPath, entryContent);
917
+ logger2.debug(
918
+ `Running esbuild (target: ${buildOptions.target || "es2018"}, format: ${buildOptions.format})`
919
+ );
1057
920
  const outputPath = path8.resolve(buildOptions.output);
1058
- await fs8.ensureDir(path8.dirname(outputPath));
921
+ await fs7.ensureDir(path8.dirname(outputPath));
1059
922
  const esbuildOptions = createEsbuildOptions(
1060
923
  buildOptions,
1061
924
  entryPath,
@@ -1072,10 +935,13 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1072
935
  buildOptions.code || ""
1073
936
  );
1074
937
  }
1075
- logger2.gray(`Output: ${outputPath}`);
938
+ const outputStats = await fs7.stat(outputPath);
939
+ const sizeKB = (outputStats.size / 1024).toFixed(1);
940
+ const buildTime = ((Date.now() - bundleStartTime) / 1e3).toFixed(1);
941
+ logger2.log(`Output: ${outputPath} (${sizeKB} KB, ${buildTime}s)`);
1076
942
  if (buildOptions.cache !== false) {
1077
943
  const configContent = generateCacheKeyContent(flowConfig, buildOptions);
1078
- const buildOutput = await fs8.readFile(outputPath, "utf-8");
944
+ const buildOutput = await fs7.readFile(outputPath, "utf-8");
1079
945
  await cacheBuild(configContent, buildOutput);
1080
946
  logger2.debug("Build cached for future use");
1081
947
  }
@@ -1097,21 +963,13 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1097
963
  logger2
1098
964
  );
1099
965
  }
1100
- if (!buildOptions.tempDir) {
1101
- await fs8.remove(TEMP_DIR);
1102
- logger2.debug("Cleaned up temporary files");
1103
- }
1104
966
  return stats;
1105
967
  } catch (error) {
1106
- if (!buildOptions.tempDir) {
1107
- await fs8.remove(TEMP_DIR).catch(() => {
1108
- });
1109
- }
1110
968
  throw error;
1111
969
  }
1112
970
  }
1113
971
  async function collectBundleStats(outputPath, packages, startTime, entryContent) {
1114
- const stats = await fs8.stat(outputPath);
972
+ const stats = await fs7.stat(outputPath);
1115
973
  const totalSize = stats.size;
1116
974
  const buildTime = Date.now() - startTime;
1117
975
  const packageStats = Object.entries(packages).map(([name, pkg]) => {
@@ -1439,6 +1297,11 @@ function generatePlatformWrapper(configObject, userCode, buildOptions) {
1439
1297
  ` : "";
1440
1298
  return `export default async function(context = {}) {
1441
1299
  const config = ${configObject};${codeSection}
1300
+ // Apply context overrides (e.g., logger config from CLI)
1301
+ if (context.logger) {
1302
+ config.logger = { ...config.logger, ...context.logger };
1303
+ }
1304
+
1442
1305
  return await startFlow(config);
1443
1306
  }`;
1444
1307
  }
@@ -1472,130 +1335,118 @@ async function bundleCommand(options) {
1472
1335
  const timer = createTimer();
1473
1336
  timer.start();
1474
1337
  const logger2 = createCommandLogger(options);
1475
- const dockerArgs = buildCommonDockerArgs(options);
1476
- if (options.flow) dockerArgs.push("--flow", options.flow);
1477
- if (options.all) dockerArgs.push("--all");
1478
- if (options.stats) dockerArgs.push("--stats");
1479
- if (options.cache === false) dockerArgs.push("--no-cache");
1480
- await executeCommand(
1481
- async () => {
1338
+ if (options.dryRun) {
1339
+ logger2.log(`[DRY-RUN] Would execute bundle with config: ${options.config}`);
1340
+ return;
1341
+ }
1342
+ try {
1343
+ if (options.flow && options.all) {
1344
+ throw new Error("Cannot use both --flow and --all flags together");
1345
+ }
1346
+ const configPath = resolveAsset(options.config, "config");
1347
+ const rawConfig = await loadJsonConfig(configPath);
1348
+ const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger: logger2 }) : [
1349
+ loadBundleConfig(rawConfig, {
1350
+ configPath,
1351
+ flowName: options.flow,
1352
+ logger: logger2
1353
+ })
1354
+ ];
1355
+ const results = [];
1356
+ for (const {
1357
+ flowConfig,
1358
+ buildOptions,
1359
+ flowName,
1360
+ isMultiFlow
1361
+ } of configsToBundle) {
1482
1362
  try {
1483
- if (options.flow && options.all) {
1484
- throw new Error("Cannot use both --flow and --all flags together");
1363
+ if (options.cache !== void 0) {
1364
+ buildOptions.cache = options.cache;
1485
1365
  }
1486
- logger2.info("\u{1F4E6} Reading configuration...");
1487
- const configPath = resolveAsset(options.config, "config");
1488
- const rawConfig = await loadJsonConfig(configPath);
1489
- const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger: logger2 }) : [
1490
- loadBundleConfig(rawConfig, {
1491
- configPath,
1492
- flowName: options.flow,
1493
- logger: logger2
1494
- })
1495
- ];
1496
- const results = [];
1497
- for (const {
1366
+ const configBasename = path9.basename(configPath);
1367
+ if (isMultiFlow || options.all) {
1368
+ logger2.log(`Bundling ${configBasename} (flow: ${flowName})...`);
1369
+ } else {
1370
+ logger2.log(`Bundling ${configBasename}...`);
1371
+ }
1372
+ const shouldCollectStats = options.stats || options.json;
1373
+ const stats = await bundleCore(
1498
1374
  flowConfig,
1499
1375
  buildOptions,
1376
+ logger2,
1377
+ shouldCollectStats
1378
+ );
1379
+ results.push({
1500
1380
  flowName,
1501
- isMultiFlow
1502
- } of configsToBundle) {
1503
- try {
1504
- if (options.cache !== void 0) {
1505
- buildOptions.cache = options.cache;
1506
- }
1507
- if (isMultiFlow || options.all) {
1508
- logger2.info(`
1509
- \u{1F527} Building flow: ${flowName}`);
1510
- } else {
1511
- logger2.info("\u{1F527} Starting bundle process...");
1512
- }
1513
- const shouldCollectStats = options.stats || options.json;
1514
- const stats = await bundleCore(
1515
- flowConfig,
1516
- buildOptions,
1517
- logger2,
1518
- shouldCollectStats
1519
- );
1520
- results.push({
1521
- flowName,
1522
- success: true,
1523
- stats
1524
- });
1525
- if (!options.json && !options.all && options.stats && stats) {
1526
- displayStats(stats, logger2);
1527
- }
1528
- } catch (error) {
1529
- const errorMessage = getErrorMessage(error);
1530
- results.push({
1531
- flowName,
1532
- success: false,
1533
- error: errorMessage
1534
- });
1535
- if (!options.all) {
1536
- throw error;
1537
- }
1538
- }
1381
+ success: true,
1382
+ stats
1383
+ });
1384
+ if (!options.json && !options.all && options.stats && stats) {
1385
+ displayStats(stats, logger2);
1539
1386
  }
1540
- const duration = timer.end() / 1e3;
1541
- const successCount = results.filter((r) => r.success).length;
1542
- const failureCount = results.filter((r) => !r.success).length;
1543
- if (options.json) {
1544
- const outputLogger = createLogger({ silent: false, json: false });
1545
- const output = failureCount === 0 ? createSuccessOutput(
1546
- {
1547
- flows: results,
1548
- summary: {
1549
- total: results.length,
1550
- success: successCount,
1551
- failed: failureCount
1552
- }
1553
- },
1554
- duration
1555
- ) : createErrorOutput(
1556
- `${failureCount} flow(s) failed to build`,
1557
- duration
1387
+ if (options.dockerfile && !options.all) {
1388
+ const dockerfilePath = path9.join(
1389
+ path9.dirname(buildOptions.output),
1390
+ "Dockerfile"
1558
1391
  );
1559
- outputLogger.log("white", JSON.stringify(output, null, 2));
1560
- } else {
1561
- if (options.all) {
1562
- logger2.info(`
1563
- \u{1F4CA} Build Summary:`);
1564
- logger2.info(` Total: ${results.length}`);
1565
- logger2.success(` \u2705 Success: ${successCount}`);
1566
- if (failureCount > 0) {
1567
- logger2.error(` \u274C Failed: ${failureCount}`);
1568
- }
1569
- }
1570
- if (failureCount === 0) {
1571
- logger2.success(
1572
- `
1573
- \u2705 Bundle created successfully in ${timer.format()}`
1574
- );
1575
- } else {
1576
- throw new Error(`${failureCount} flow(s) failed to build`);
1577
- }
1392
+ await generateDockerfile(dockerfilePath, buildOptions.output, logger2);
1578
1393
  }
1579
1394
  } catch (error) {
1580
- const duration = timer.getElapsed() / 1e3;
1581
1395
  const errorMessage = getErrorMessage(error);
1582
- if (options.json) {
1583
- const outputLogger = createLogger({ silent: false, json: false });
1584
- const output = createErrorOutput(errorMessage, duration);
1585
- outputLogger.log("white", JSON.stringify(output, null, 2));
1586
- } else {
1587
- logger2.error("\u274C Bundle failed:");
1588
- logger2.error(errorMessage);
1396
+ results.push({
1397
+ flowName,
1398
+ success: false,
1399
+ error: errorMessage
1400
+ });
1401
+ if (!options.all) {
1402
+ throw error;
1589
1403
  }
1590
- process.exit(1);
1591
1404
  }
1592
- },
1593
- "bundle",
1594
- dockerArgs,
1595
- options,
1596
- logger2,
1597
- options.config
1598
- );
1405
+ }
1406
+ const duration = timer.end() / 1e3;
1407
+ const successCount = results.filter((r) => r.success).length;
1408
+ const failureCount = results.filter((r) => !r.success).length;
1409
+ if (options.json) {
1410
+ const output = failureCount === 0 ? createSuccessOutput(
1411
+ {
1412
+ flows: results,
1413
+ summary: {
1414
+ total: results.length,
1415
+ success: successCount,
1416
+ failed: failureCount
1417
+ }
1418
+ },
1419
+ duration
1420
+ ) : createErrorOutput(
1421
+ `${failureCount} flow(s) failed to build`,
1422
+ duration
1423
+ );
1424
+ logger2.json(output);
1425
+ } else {
1426
+ if (options.all) {
1427
+ logger2.log(
1428
+ `
1429
+ Build Summary: ${successCount}/${results.length} succeeded`
1430
+ );
1431
+ if (failureCount > 0) {
1432
+ logger2.error(`Failed: ${failureCount}`);
1433
+ }
1434
+ }
1435
+ if (failureCount > 0) {
1436
+ throw new Error(`${failureCount} flow(s) failed to build`);
1437
+ }
1438
+ }
1439
+ } catch (error) {
1440
+ const duration = timer.getElapsed() / 1e3;
1441
+ const errorMessage = getErrorMessage(error);
1442
+ if (options.json) {
1443
+ const output = createErrorOutput(errorMessage, duration);
1444
+ logger2.json(output);
1445
+ } else {
1446
+ logger2.error(`Error: ${errorMessage}`);
1447
+ }
1448
+ process.exit(1);
1449
+ }
1599
1450
  }
1600
1451
  async function bundle(configOrPath, options = {}) {
1601
1452
  let rawConfig;
@@ -1622,6 +1473,21 @@ async function bundle(configOrPath, options = {}) {
1622
1473
  options.stats ?? false
1623
1474
  );
1624
1475
  }
1476
+ async function generateDockerfile(dockerfilePath, bundleOutput, logger2) {
1477
+ const bundleFilename = path9.basename(bundleOutput);
1478
+ const dockerfile = `# Generated by walkeros CLI
1479
+ FROM walkeros/flow:latest
1480
+
1481
+ COPY ${bundleFilename} /app/flow/bundle.mjs
1482
+
1483
+ ENV MODE=collect
1484
+ ENV BUNDLE=/app/flow/bundle.mjs
1485
+
1486
+ EXPOSE 8080
1487
+ `;
1488
+ await fs8.writeFile(dockerfilePath, dockerfile);
1489
+ logger2.log(`Dockerfile: ${dockerfilePath}`);
1490
+ }
1625
1491
 
1626
1492
  // src/commands/simulate/simulator.ts
1627
1493
  import path10 from "path";
@@ -1662,9 +1528,9 @@ var CallTracker = class {
1662
1528
  }
1663
1529
  for (const fullPath of paths) {
1664
1530
  const [destKey, ...pathParts] = fullPath.split(":");
1665
- const path15 = pathParts.join(":");
1666
- if (!path15) continue;
1667
- const cleanPath = path15.replace(/^call:/, "");
1531
+ const path14 = pathParts.join(":");
1532
+ if (!path14) continue;
1533
+ const cleanPath = path14.replace(/^call:/, "");
1668
1534
  const parts = cleanPath.split(".");
1669
1535
  let current = wrapped;
1670
1536
  let source = env;
@@ -1745,11 +1611,11 @@ function buildSandboxFromEnvs(envs, destinations, tracker) {
1745
1611
  return sandbox;
1746
1612
  }
1747
1613
  function waitForWindowProperty(window, prop, timeout = 5e3) {
1748
- return new Promise((resolve, reject) => {
1614
+ return new Promise((resolve3, reject) => {
1749
1615
  const start = Date.now();
1750
1616
  const check = () => {
1751
1617
  if (window[prop] !== void 0) {
1752
- resolve();
1618
+ resolve3();
1753
1619
  } else if (Date.now() - start > timeout) {
1754
1620
  reject(
1755
1621
  new Error(
@@ -1848,7 +1714,7 @@ function injectGlobalMocks(mocks) {
1848
1714
  }
1849
1715
  };
1850
1716
  }
1851
- async function executeInNode(bundlePath, destinations, event, tracker, envs, timeout = 3e4) {
1717
+ async function executeInNode(bundlePath, destinations, event, tracker, envs, timeout = 3e4, context = {}) {
1852
1718
  const start = Date.now();
1853
1719
  const globalMocks = buildGlobalMocksFromEnvs(envs, destinations, tracker);
1854
1720
  const cleanupMocks = injectGlobalMocks(globalMocks);
@@ -1859,16 +1725,19 @@ async function executeInNode(bundlePath, destinations, event, tracker, envs, tim
1859
1725
  if (!module.default || typeof module.default !== "function") {
1860
1726
  throw new Error("Bundle does not export default factory function");
1861
1727
  }
1862
- const result = await module.default();
1863
- if (!result || !result.elb || typeof result.elb !== "function") {
1728
+ const result = await module.default(context);
1729
+ if (!result || !result.collector || typeof result.collector.push !== "function") {
1864
1730
  throw new Error(
1865
- "Factory function did not return valid result with elb"
1731
+ "Factory function did not return valid result with collector"
1866
1732
  );
1867
1733
  }
1868
1734
  const { collector, elb } = result;
1869
1735
  let elbResult;
1870
1736
  try {
1871
- elbResult = await elb(event.name, event.data);
1737
+ elbResult = await collector.push({
1738
+ name: event.name,
1739
+ data: event.data
1740
+ });
1872
1741
  } catch (error) {
1873
1742
  throw new Error(`Event execution failed: ${getErrorMessage(error)}`);
1874
1743
  }
@@ -1916,10 +1785,7 @@ async function loadDestinationEnvs(destinations) {
1916
1785
  simulation: envModule.simulation || []
1917
1786
  };
1918
1787
  }
1919
- } catch (error) {
1920
- console.warn(
1921
- `Warning: Could not load env for destination "${destKey}": ${error instanceof Error ? error.message : String(error)}`
1922
- );
1788
+ } catch {
1923
1789
  }
1924
1790
  }
1925
1791
  return envs;
@@ -1929,29 +1795,21 @@ async function loadDestinationEnvs(destinations) {
1929
1795
  function generateId() {
1930
1796
  return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
1931
1797
  }
1932
- async function simulateCore(configPath, event, options = {}) {
1798
+ async function simulateCore(inputPath, event, options = {}) {
1933
1799
  const logger2 = createLogger({
1934
1800
  verbose: options.verbose || false,
1935
1801
  silent: options.silent || false,
1936
1802
  json: options.json || false
1937
1803
  });
1938
1804
  try {
1939
- logger2.info("\u{1F3AF} Starting walkerOS simulation...");
1940
- logger2.info("\u{1F4E6} Loading bundle configuration...");
1941
- const fullConfigPath = path10.resolve(configPath);
1942
- const rawConfig = await loadJsonConfig(fullConfigPath);
1943
- loadBundleConfig(rawConfig, { configPath: fullConfigPath });
1944
- logger2.info(`\u{1F680} Executing simulation with event: ${JSON.stringify(event)}`);
1945
- const result = await executeSimulation(event, fullConfigPath);
1946
- if (result.success) {
1947
- logger2.info(`\u2705 Simulation completed successfully`);
1948
- } else {
1949
- logger2.error(`\u274C Simulation failed: ${result.error}`);
1950
- }
1805
+ logger2.debug(`Simulating event: ${JSON.stringify(event)}`);
1806
+ const result = await executeSimulation(event, inputPath, options.platform, {
1807
+ logger: logger2,
1808
+ verbose: options.verbose
1809
+ });
1951
1810
  return result;
1952
1811
  } catch (error) {
1953
1812
  const errorMessage = getErrorMessage(error);
1954
- logger2.error(`\u{1F4A5} Simulation error: ${errorMessage}`);
1955
1813
  return {
1956
1814
  success: false,
1957
1815
  error: errorMessage
@@ -1968,87 +1826,43 @@ function formatSimulationResult(result, options = {}) {
1968
1826
  return JSON.stringify(output, null, 2);
1969
1827
  }
1970
1828
  if (result.success) {
1971
- return "\u2705 Simulation completed successfully";
1829
+ return "Simulation completed";
1972
1830
  } else {
1973
- return `\u274C Simulation failed: ${result.error}`;
1831
+ return `Simulation failed: ${result.error}`;
1974
1832
  }
1975
1833
  }
1976
- async function executeSimulation(event, configPath) {
1834
+ async function executeSimulation(event, inputPath, platformOverride, options = {}) {
1977
1835
  const startTime = Date.now();
1978
- let bundlePath;
1979
- const tempDir = getTempDir();
1836
+ const tempDir = getTmpPath();
1837
+ const collectorLoggerConfig = options.logger ? createCollectorLoggerConfig(options.logger, options.verbose) : void 0;
1980
1838
  try {
1839
+ await fs10.ensureDir(tempDir);
1840
+ const detected = await detectInput(inputPath, platformOverride);
1981
1841
  if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
1982
1842
  throw new Error(
1983
1843
  'Event must be an object with a "name" property of type string'
1984
1844
  );
1985
1845
  }
1986
1846
  const typedEvent = event;
1987
- await fs10.ensureDir(tempDir);
1988
- const rawConfig = await loadJsonConfig(configPath);
1989
- const { flowConfig, buildOptions } = loadBundleConfig(rawConfig, {
1990
- configPath
1991
- });
1992
- const platform = getPlatform2(flowConfig);
1993
- const tracker = new CallTracker();
1994
- const tempOutput = path10.join(
1995
- tempDir,
1996
- `simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
1997
- );
1998
- const destinations = flowConfig.destinations;
1999
- const simulationBuildOptions = {
2000
- ...buildOptions,
2001
- code: buildOptions.code || "",
2002
- output: tempOutput,
2003
- tempDir,
2004
- ...platform === "web" ? {
2005
- format: "iife",
2006
- platform: "browser",
2007
- windowCollector: "collector",
2008
- windowElb: "elb"
2009
- } : {
2010
- format: "esm",
2011
- platform: "node"
2012
- }
2013
- };
2014
- await bundleCore(
2015
- flowConfig,
2016
- simulationBuildOptions,
2017
- createLogger({ silent: true }),
2018
- false
2019
- );
2020
- bundlePath = tempOutput;
2021
- const envs = await loadDestinationEnvs(destinations || {});
2022
- let result;
2023
- if (platform === "web") {
2024
- result = await executeInJSDOM(
2025
- tempOutput,
2026
- destinations || {},
1847
+ if (detected.type === "config") {
1848
+ return await executeConfigSimulation(
1849
+ detected.content,
1850
+ inputPath,
2027
1851
  typedEvent,
2028
- tracker,
2029
- envs,
2030
- 1e4
1852
+ tempDir,
1853
+ startTime,
1854
+ collectorLoggerConfig
2031
1855
  );
2032
1856
  } else {
2033
- result = await executeInNode(
2034
- tempOutput,
2035
- destinations || {},
1857
+ return await executeBundleSimulation(
1858
+ detected.content,
1859
+ detected.platform,
2036
1860
  typedEvent,
2037
- tracker,
2038
- envs,
2039
- 3e4
1861
+ tempDir,
1862
+ startTime,
1863
+ collectorLoggerConfig
2040
1864
  );
2041
1865
  }
2042
- const elbResult = result.elbResult;
2043
- const usage = result.usage;
2044
- const duration = Date.now() - startTime;
2045
- return {
2046
- success: true,
2047
- elbResult,
2048
- usage,
2049
- duration,
2050
- logs: []
2051
- };
2052
1866
  } catch (error) {
2053
1867
  const duration = Date.now() - startTime;
2054
1868
  return {
@@ -2063,63 +1877,152 @@ async function executeSimulation(event, configPath) {
2063
1877
  }
2064
1878
  }
2065
1879
  }
1880
+ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir, startTime, loggerConfig2) {
1881
+ const { flowConfig, buildOptions } = await loadFlowConfig(configPath);
1882
+ const platform = getPlatform2(flowConfig);
1883
+ const tracker = new CallTracker();
1884
+ const tempOutput = path10.join(
1885
+ tempDir,
1886
+ `simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
1887
+ );
1888
+ const destinations = flowConfig.destinations;
1889
+ const simulationBuildOptions = {
1890
+ ...buildOptions,
1891
+ code: buildOptions.code || "",
1892
+ output: tempOutput,
1893
+ tempDir,
1894
+ ...platform === "web" ? {
1895
+ format: "iife",
1896
+ platform: "browser",
1897
+ windowCollector: "collector",
1898
+ windowElb: "elb"
1899
+ } : {
1900
+ format: "esm",
1901
+ platform: "node"
1902
+ }
1903
+ };
1904
+ await bundleCore(
1905
+ flowConfig,
1906
+ simulationBuildOptions,
1907
+ createLogger({ silent: true }),
1908
+ false
1909
+ );
1910
+ const envs = await loadDestinationEnvs(destinations || {});
1911
+ let result;
1912
+ if (platform === "web") {
1913
+ result = await executeInJSDOM(
1914
+ tempOutput,
1915
+ destinations || {},
1916
+ typedEvent,
1917
+ tracker,
1918
+ envs,
1919
+ 1e4
1920
+ );
1921
+ } else {
1922
+ result = await executeInNode(
1923
+ tempOutput,
1924
+ destinations || {},
1925
+ typedEvent,
1926
+ tracker,
1927
+ envs,
1928
+ 3e4,
1929
+ loggerConfig2 ? { logger: loggerConfig2 } : {}
1930
+ );
1931
+ }
1932
+ const duration = Date.now() - startTime;
1933
+ return {
1934
+ success: true,
1935
+ elbResult: result.elbResult,
1936
+ usage: result.usage,
1937
+ duration,
1938
+ logs: []
1939
+ };
1940
+ }
1941
+ async function executeBundleSimulation(bundleContent, platform, typedEvent, tempDir, startTime, loggerConfig2) {
1942
+ const tempOutput = path10.join(
1943
+ tempDir,
1944
+ `bundle-${generateId()}.${platform === "server" ? "mjs" : "js"}`
1945
+ );
1946
+ await fs10.writeFile(tempOutput, bundleContent, "utf8");
1947
+ const tracker = new CallTracker();
1948
+ let result;
1949
+ if (platform === "web") {
1950
+ result = await executeInJSDOM(
1951
+ tempOutput,
1952
+ {},
1953
+ typedEvent,
1954
+ tracker,
1955
+ {},
1956
+ 1e4
1957
+ );
1958
+ } else {
1959
+ result = await executeInNode(
1960
+ tempOutput,
1961
+ {},
1962
+ typedEvent,
1963
+ tracker,
1964
+ {},
1965
+ 3e4,
1966
+ loggerConfig2 ? { logger: loggerConfig2 } : {}
1967
+ );
1968
+ }
1969
+ const duration = Date.now() - startTime;
1970
+ return {
1971
+ success: true,
1972
+ elbResult: result.elbResult,
1973
+ usage: result.usage,
1974
+ duration,
1975
+ logs: []
1976
+ };
1977
+ }
2066
1978
 
2067
1979
  // src/commands/simulate/index.ts
2068
1980
  async function simulateCommand(options) {
2069
1981
  const logger2 = createCommandLogger(options);
2070
- const dockerArgs = buildCommonDockerArgs(options);
2071
- if (options.event) dockerArgs.push("--event", options.event);
2072
- await executeCommand(
2073
- async () => {
2074
- const startTime = Date.now();
2075
- try {
2076
- const event = await loadJsonFromSource(options.event, {
2077
- name: "event"
2078
- });
2079
- const result = await simulateCore(options.config, event, {
2080
- json: options.json,
2081
- verbose: options.verbose,
2082
- silent: options.silent
2083
- });
2084
- const resultWithDuration = {
2085
- ...result,
2086
- duration: (Date.now() - startTime) / 1e3
2087
- };
2088
- const outputLogger = createLogger({ silent: false, json: false });
2089
- const output = formatSimulationResult(resultWithDuration, {
2090
- json: options.json
2091
- });
2092
- outputLogger.log("white", output);
2093
- if (!result.success) {
2094
- process.exit(1);
2095
- }
2096
- } catch (error) {
2097
- const errorMessage = getErrorMessage(error);
2098
- if (options.json) {
2099
- const outputLogger = createLogger({ silent: false, json: false });
2100
- const errorOutput = JSON.stringify(
2101
- {
2102
- success: false,
2103
- error: errorMessage,
2104
- duration: (Date.now() - startTime) / 1e3
2105
- },
2106
- null,
2107
- 2
2108
- );
2109
- outputLogger.log("white", errorOutput);
2110
- } else {
2111
- const errorLogger = createLogger({ silent: false, json: false });
2112
- errorLogger.error(`\u274C Simulate command failed: ${errorMessage}`);
2113
- }
2114
- process.exit(1);
2115
- }
2116
- },
2117
- "simulate",
2118
- dockerArgs,
2119
- options,
2120
- logger2,
2121
- options.config
2122
- );
1982
+ if (options.dryRun) {
1983
+ logger2.log(
1984
+ `[DRY-RUN] Would execute simulate with config: ${options.config}`
1985
+ );
1986
+ return;
1987
+ }
1988
+ const startTime = Date.now();
1989
+ try {
1990
+ const event = await loadJsonFromSource(options.event, {
1991
+ name: "event"
1992
+ });
1993
+ const result = await simulateCore(options.config, event, {
1994
+ json: options.json,
1995
+ verbose: options.verbose,
1996
+ silent: options.silent
1997
+ });
1998
+ const resultWithDuration = {
1999
+ ...result,
2000
+ duration: (Date.now() - startTime) / 1e3
2001
+ };
2002
+ if (options.json) {
2003
+ logger2.json(resultWithDuration);
2004
+ } else {
2005
+ const output = formatSimulationResult(resultWithDuration, {
2006
+ json: false
2007
+ });
2008
+ logger2.log(output);
2009
+ }
2010
+ if (!result.success) {
2011
+ process.exit(1);
2012
+ }
2013
+ } catch (error) {
2014
+ const errorMessage = getErrorMessage(error);
2015
+ if (options.json) {
2016
+ logger2.json({
2017
+ success: false,
2018
+ error: errorMessage,
2019
+ duration: (Date.now() - startTime) / 1e3
2020
+ });
2021
+ } else {
2022
+ logger2.error(`Error: ${errorMessage}`);
2023
+ }
2024
+ process.exit(1);
2025
+ }
2123
2026
  }
2124
2027
  async function simulate(configOrPath, event, options = {}) {
2125
2028
  if (typeof configOrPath !== "string") {
@@ -2137,152 +2040,182 @@ async function simulate(configOrPath, event, options = {}) {
2137
2040
  import path11 from "path";
2138
2041
  import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
2139
2042
  import fs11 from "fs-extra";
2140
- import { getPlatform as getPlatform3 } from "@walkeros/core";
2043
+ import {
2044
+ getPlatform as getPlatform3
2045
+ } from "@walkeros/core";
2141
2046
  import { schemas as schemas2 } from "@walkeros/core/dev";
2142
2047
  async function pushCommand(options) {
2143
2048
  const logger2 = createCommandLogger(options);
2144
- const dockerArgs = buildCommonDockerArgs(options);
2145
- dockerArgs.push("--event", options.event);
2146
- if (options.flow) dockerArgs.push("--flow", options.flow);
2147
- await executeCommand(
2148
- async () => {
2149
- const startTime = Date.now();
2150
- try {
2151
- logger2.info("\u{1F4E5} Loading event...");
2152
- const event = await loadJsonFromSource(options.event, {
2153
- name: "event"
2154
- });
2155
- const eventResult = schemas2.PartialEventSchema.safeParse(event);
2156
- if (!eventResult.success) {
2157
- const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
2158
- throw new Error(`Invalid event: ${errors}`);
2159
- }
2160
- const parsedEvent = eventResult.data;
2161
- if (!parsedEvent.name) {
2162
- throw new Error('Invalid event: Missing required "name" property');
2163
- }
2164
- const validatedEvent = {
2165
- name: parsedEvent.name,
2166
- data: parsedEvent.data || {}
2167
- };
2168
- if (!validatedEvent.name.includes(" ")) {
2169
- logger2.warn(
2170
- `Event name "${validatedEvent.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
2171
- );
2049
+ const startTime = Date.now();
2050
+ let tempDir;
2051
+ try {
2052
+ logger2.debug("Loading event");
2053
+ const event = await loadJsonFromSource(options.event, {
2054
+ name: "event"
2055
+ });
2056
+ const eventResult = schemas2.PartialEventSchema.safeParse(event);
2057
+ if (!eventResult.success) {
2058
+ const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
2059
+ throw new Error(`Invalid event: ${errors}`);
2060
+ }
2061
+ const parsedEvent = eventResult.data;
2062
+ if (!parsedEvent.name) {
2063
+ throw new Error('Invalid event: Missing required "name" property');
2064
+ }
2065
+ const validatedEvent = {
2066
+ name: parsedEvent.name,
2067
+ data: parsedEvent.data || {}
2068
+ };
2069
+ if (!validatedEvent.name.includes(" ")) {
2070
+ logger2.log(
2071
+ `Warning: Event name "${validatedEvent.name}" should follow "ENTITY ACTION" format (e.g., "page view")`
2072
+ );
2073
+ }
2074
+ logger2.debug("Detecting input type");
2075
+ const detected = await detectInput(options.config, options.platform);
2076
+ let result;
2077
+ if (detected.type === "config") {
2078
+ result = await executeConfigPush(
2079
+ options,
2080
+ validatedEvent,
2081
+ logger2,
2082
+ (dir) => {
2083
+ tempDir = dir;
2172
2084
  }
2173
- logger2.info("\u{1F4E6} Loading flow configuration...");
2174
- const configPath = path11.resolve(options.config);
2175
- const rawConfig = await loadJsonConfig(configPath);
2176
- const { flowConfig, buildOptions, flowName, isMultiFlow } = loadBundleConfig(rawConfig, {
2177
- configPath: options.config,
2178
- flowName: options.flow,
2179
- logger: logger2
2180
- });
2181
- const platform = getPlatform3(flowConfig);
2182
- logger2.info("\u{1F528} Bundling flow configuration...");
2183
- const configDir = path11.dirname(configPath);
2184
- const tempDir = path11.join(
2185
- configDir,
2186
- ".tmp",
2187
- `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
2188
- );
2189
- await fs11.ensureDir(tempDir);
2190
- const tempPath = path11.join(
2191
- tempDir,
2192
- `bundle.${platform === "web" ? "js" : "mjs"}`
2193
- );
2194
- const pushBuildOptions = {
2195
- ...buildOptions,
2196
- output: tempPath,
2197
- // Web uses IIFE for browser-like execution, server uses ESM
2198
- format: platform === "web" ? "iife" : "esm",
2199
- platform: platform === "web" ? "browser" : "node",
2200
- ...platform === "web" && {
2201
- windowCollector: "collector",
2202
- windowElb: "elb"
2085
+ );
2086
+ } else {
2087
+ const collectorLoggerConfig = createCollectorLoggerConfig(
2088
+ logger2,
2089
+ options.verbose
2090
+ );
2091
+ result = await executeBundlePush(
2092
+ detected.content,
2093
+ detected.platform,
2094
+ validatedEvent,
2095
+ logger2,
2096
+ (dir) => {
2097
+ tempDir = dir;
2098
+ },
2099
+ { logger: collectorLoggerConfig }
2100
+ );
2101
+ }
2102
+ const duration = Date.now() - startTime;
2103
+ if (options.json) {
2104
+ logger2.json({
2105
+ success: result.success,
2106
+ event: result.elbResult,
2107
+ duration
2108
+ });
2109
+ } else {
2110
+ if (result.success) {
2111
+ logger2.log("Event pushed successfully");
2112
+ if (result.elbResult && typeof result.elbResult === "object") {
2113
+ const pushResult = result.elbResult;
2114
+ if ("id" in pushResult && pushResult.id) {
2115
+ logger2.log(` Event ID: ${pushResult.id}`);
2203
2116
  }
2204
- };
2205
- await bundleCore(flowConfig, pushBuildOptions, logger2, false);
2206
- logger2.debug(`Bundle created: ${tempPath}`);
2207
- let result;
2208
- if (platform === "web") {
2209
- logger2.info("\u{1F310} Executing in web environment (JSDOM)...");
2210
- result = await executeWebPush(tempPath, validatedEvent, logger2);
2211
- } else if (platform === "server") {
2212
- logger2.info("\u{1F5A5}\uFE0F Executing in server environment (Node.js)...");
2213
- result = await executeServerPush(tempPath, validatedEvent, logger2);
2214
- } else {
2215
- throw new Error(`Unsupported platform: ${platform}`);
2216
- }
2217
- const duration = Date.now() - startTime;
2218
- if (options.json) {
2219
- const outputLogger = createLogger({ silent: false, json: false });
2220
- outputLogger.log(
2221
- "white",
2222
- JSON.stringify(
2223
- {
2224
- success: result.success,
2225
- event: result.elbResult,
2226
- duration
2227
- },
2228
- null,
2229
- 2
2230
- )
2231
- );
2232
- } else {
2233
- if (result.success) {
2234
- logger2.success("\u2705 Event pushed successfully");
2235
- if (result.elbResult && typeof result.elbResult === "object") {
2236
- const pushResult = result.elbResult;
2237
- if ("id" in pushResult && pushResult.id) {
2238
- logger2.info(` Event ID: ${pushResult.id}`);
2239
- }
2240
- if ("entity" in pushResult && pushResult.entity) {
2241
- logger2.info(` Entity: ${pushResult.entity}`);
2242
- }
2243
- if ("action" in pushResult && pushResult.action) {
2244
- logger2.info(` Action: ${pushResult.action}`);
2245
- }
2246
- }
2247
- logger2.info(` Duration: ${duration}ms`);
2248
- } else {
2249
- logger2.error(`\u274C Push failed: ${result.error}`);
2250
- process.exit(1);
2117
+ if ("entity" in pushResult && pushResult.entity) {
2118
+ logger2.log(` Entity: ${pushResult.entity}`);
2119
+ }
2120
+ if ("action" in pushResult && pushResult.action) {
2121
+ logger2.log(` Action: ${pushResult.action}`);
2251
2122
  }
2252
2123
  }
2253
- try {
2254
- await fs11.remove(tempDir);
2255
- } catch {
2256
- }
2257
- } catch (error) {
2258
- const duration = Date.now() - startTime;
2259
- const errorMessage = getErrorMessage(error);
2260
- if (options.json) {
2261
- const outputLogger = createLogger({ silent: false, json: false });
2262
- outputLogger.log(
2263
- "white",
2264
- JSON.stringify(
2265
- {
2266
- success: false,
2267
- error: errorMessage,
2268
- duration
2269
- },
2270
- null,
2271
- 2
2272
- )
2273
- );
2274
- } else {
2275
- logger2.error(`\u274C Push command failed: ${errorMessage}`);
2276
- }
2124
+ logger2.log(` Duration: ${duration}ms`);
2125
+ } else {
2126
+ logger2.error(`Error: ${result.error}`);
2277
2127
  process.exit(1);
2278
2128
  }
2279
- },
2280
- "push",
2281
- dockerArgs,
2282
- options,
2283
- logger2,
2284
- options.config
2129
+ }
2130
+ } catch (error) {
2131
+ const duration = Date.now() - startTime;
2132
+ const errorMessage = getErrorMessage(error);
2133
+ if (options.json) {
2134
+ logger2.json({
2135
+ success: false,
2136
+ error: errorMessage,
2137
+ duration
2138
+ });
2139
+ } else {
2140
+ logger2.error(`Error: ${errorMessage}`);
2141
+ }
2142
+ process.exit(1);
2143
+ } finally {
2144
+ if (tempDir) {
2145
+ await fs11.remove(tempDir).catch(() => {
2146
+ });
2147
+ }
2148
+ }
2149
+ }
2150
+ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
2151
+ logger2.debug("Loading flow configuration");
2152
+ const { flowConfig, buildOptions } = await loadFlowConfig(options.config, {
2153
+ flowName: options.flow,
2154
+ logger: logger2
2155
+ });
2156
+ const platform = getPlatform3(flowConfig);
2157
+ logger2.debug("Bundling flow configuration");
2158
+ const configDir = buildOptions.configDir || process.cwd();
2159
+ const tempDir = path11.join(
2160
+ configDir,
2161
+ ".tmp",
2162
+ `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
2163
+ );
2164
+ setTempDir(tempDir);
2165
+ await fs11.ensureDir(tempDir);
2166
+ const tempPath = path11.join(
2167
+ tempDir,
2168
+ `bundle.${platform === "web" ? "js" : "mjs"}`
2169
+ );
2170
+ const pushBuildOptions = {
2171
+ ...buildOptions,
2172
+ output: tempPath,
2173
+ format: platform === "web" ? "iife" : "esm",
2174
+ platform: platform === "web" ? "browser" : "node",
2175
+ ...platform === "web" && {
2176
+ windowCollector: "collector",
2177
+ windowElb: "elb"
2178
+ }
2179
+ };
2180
+ await bundleCore(flowConfig, pushBuildOptions, logger2, false);
2181
+ logger2.debug(`Bundle created: ${tempPath}`);
2182
+ if (platform === "web") {
2183
+ logger2.debug("Executing in web environment (JSDOM)");
2184
+ return executeWebPush(tempPath, validatedEvent, logger2);
2185
+ } else if (platform === "server") {
2186
+ logger2.debug("Executing in server environment (Node.js)");
2187
+ const collectorLoggerConfig = createCollectorLoggerConfig(
2188
+ logger2,
2189
+ options.verbose
2190
+ );
2191
+ return executeServerPush(tempPath, validatedEvent, logger2, 6e4, {
2192
+ logger: collectorLoggerConfig
2193
+ });
2194
+ } else {
2195
+ throw new Error(`Unsupported platform: ${platform}`);
2196
+ }
2197
+ }
2198
+ async function executeBundlePush(bundleContent, platform, validatedEvent, logger2, setTempDir, context = {}) {
2199
+ const tempDir = path11.join(
2200
+ process.cwd(),
2201
+ ".tmp",
2202
+ `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
2285
2203
  );
2204
+ setTempDir(tempDir);
2205
+ await fs11.ensureDir(tempDir);
2206
+ const tempPath = path11.join(
2207
+ tempDir,
2208
+ `bundle.${platform === "server" ? "mjs" : "js"}`
2209
+ );
2210
+ await fs11.writeFile(tempPath, bundleContent, "utf8");
2211
+ logger2.debug(`Bundle written to: ${tempPath}`);
2212
+ if (platform === "web") {
2213
+ logger2.debug("Executing in web environment (JSDOM)");
2214
+ return executeWebPush(tempPath, validatedEvent, logger2);
2215
+ } else {
2216
+ logger2.debug("Executing in server environment (Node.js)");
2217
+ return executeServerPush(tempPath, validatedEvent, logger2, 6e4, context);
2218
+ }
2286
2219
  }
2287
2220
  async function executeWebPush(bundlePath, event, logger2) {
2288
2221
  const startTime = Date.now();
@@ -2298,16 +2231,19 @@ async function executeWebPush(bundlePath, event, logger2) {
2298
2231
  logger2.debug("Loading bundle...");
2299
2232
  const bundleCode = await fs11.readFile(bundlePath, "utf8");
2300
2233
  window.eval(bundleCode);
2301
- logger2.debug("Waiting for elb...");
2234
+ logger2.debug("Waiting for collector...");
2302
2235
  await waitForWindowProperty2(
2303
2236
  window,
2304
- "elb",
2237
+ "collector",
2305
2238
  5e3
2306
2239
  );
2307
2240
  const windowObj = window;
2308
- const elb = windowObj.elb;
2309
- logger2.info(`Pushing event: ${event.name}`);
2310
- const elbResult = await elb(event.name, event.data);
2241
+ const collector = windowObj.collector;
2242
+ logger2.log(`Pushing event: ${event.name}`);
2243
+ const elbResult = await collector.push({
2244
+ name: event.name,
2245
+ data: event.data
2246
+ });
2311
2247
  return {
2312
2248
  success: true,
2313
2249
  elbResult,
@@ -2321,7 +2257,7 @@ async function executeWebPush(bundlePath, event, logger2) {
2321
2257
  };
2322
2258
  }
2323
2259
  }
2324
- async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
2260
+ async function executeServerPush(bundlePath, event, logger2, timeout = 6e4, context = {}) {
2325
2261
  const startTime = Date.now();
2326
2262
  try {
2327
2263
  const timeoutPromise = new Promise((_, reject) => {
@@ -2337,15 +2273,18 @@ async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
2337
2273
  throw new Error("Bundle does not export default factory function");
2338
2274
  }
2339
2275
  logger2.debug("Calling factory function...");
2340
- const result = await flowModule.default();
2341
- if (!result || !result.elb || typeof result.elb !== "function") {
2276
+ const result = await flowModule.default(context);
2277
+ if (!result || !result.collector || typeof result.collector.push !== "function") {
2342
2278
  throw new Error(
2343
- "Factory function did not return valid result with elb"
2279
+ "Factory function did not return valid result with collector"
2344
2280
  );
2345
2281
  }
2346
- const { elb } = result;
2347
- logger2.info(`Pushing event: ${event.name}`);
2348
- const elbResult = await elb(event.name, event.data);
2282
+ const { collector } = result;
2283
+ logger2.log(`Pushing event: ${event.name}`);
2284
+ const elbResult = await collector.push({
2285
+ name: event.name,
2286
+ data: event.data
2287
+ });
2349
2288
  return {
2350
2289
  success: true,
2351
2290
  elbResult,
@@ -2362,11 +2301,11 @@ async function executeServerPush(bundlePath, event, logger2, timeout = 6e4) {
2362
2301
  }
2363
2302
  }
2364
2303
  function waitForWindowProperty2(window, prop, timeout = 5e3) {
2365
- return new Promise((resolve, reject) => {
2304
+ return new Promise((resolve3, reject) => {
2366
2305
  const start = Date.now();
2367
2306
  const check = () => {
2368
2307
  if (window[prop] !== void 0) {
2369
- resolve();
2308
+ resolve3();
2370
2309
  } else if (Date.now() - start > timeout) {
2371
2310
  reject(
2372
2311
  new Error(
@@ -2465,9 +2404,134 @@ function isPreBuiltConfig(configPath) {
2465
2404
 
2466
2405
  // src/commands/run/execution.ts
2467
2406
  import { createLogger as createLogger2, Level } from "@walkeros/core";
2468
- import { runFlow, runServeMode } from "@walkeros/docker";
2407
+
2408
+ // src/runtime/runner.ts
2409
+ import { pathToFileURL as pathToFileURL2 } from "url";
2410
+ import { resolve, dirname as dirname2 } from "path";
2411
+ async function runFlow(file, config, logger2, loggerConfig2) {
2412
+ logger2.info(`Loading flow from ${file}`);
2413
+ try {
2414
+ const absolutePath = resolve(file);
2415
+ const flowDir = dirname2(absolutePath);
2416
+ process.chdir(flowDir);
2417
+ const fileUrl = pathToFileURL2(absolutePath).href;
2418
+ const module = await import(fileUrl);
2419
+ if (!module.default || typeof module.default !== "function") {
2420
+ logger2.throw(
2421
+ `Invalid flow bundle: ${file} must export a default function`
2422
+ );
2423
+ }
2424
+ const flowContext = loggerConfig2 ? { ...config, logger: loggerConfig2 } : config;
2425
+ const result = await module.default(flowContext);
2426
+ if (!result || !result.collector) {
2427
+ logger2.throw(`Invalid flow bundle: ${file} must return { collector }`);
2428
+ }
2429
+ const { collector } = result;
2430
+ logger2.info("Flow running");
2431
+ if (config?.port) {
2432
+ logger2.info(`Port: ${config.port}`);
2433
+ }
2434
+ const shutdown = async (signal) => {
2435
+ logger2.info(`Received ${signal}, shutting down gracefully...`);
2436
+ try {
2437
+ if (collector.command) {
2438
+ await collector.command("shutdown");
2439
+ }
2440
+ logger2.info("Shutdown complete");
2441
+ process.exit(0);
2442
+ } catch (error) {
2443
+ const message = error instanceof Error ? error.message : String(error);
2444
+ logger2.error(`Error during shutdown: ${message}`);
2445
+ process.exit(1);
2446
+ }
2447
+ };
2448
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
2449
+ process.on("SIGINT", () => shutdown("SIGINT"));
2450
+ await new Promise(() => {
2451
+ });
2452
+ } catch (error) {
2453
+ const message = error instanceof Error ? error.message : String(error);
2454
+ logger2.error(`Failed to run flow: ${message}`);
2455
+ if (error instanceof Error && error.stack) {
2456
+ logger2.debug("Stack trace:", { stack: error.stack });
2457
+ }
2458
+ throw error;
2459
+ }
2460
+ }
2461
+
2462
+ // src/runtime/serve.ts
2463
+ import express from "express";
2464
+ import { resolve as resolve2 } from "path";
2465
+ async function runServeMode(config, logger2) {
2466
+ const port = process.env.PORT ? parseInt(process.env.PORT, 10) : config?.port || 8080;
2467
+ const host = process.env.HOST || config?.host || "0.0.0.0";
2468
+ const file = resolve2(
2469
+ process.env.BUNDLE || config?.file || "./dist/walker.js"
2470
+ );
2471
+ const serveName = process.env.SERVE_NAME || config?.serveName || "walker.js";
2472
+ const servePath = process.env.SERVE_PATH || config?.servePath || "";
2473
+ const urlPath = servePath ? `/${servePath}/${serveName}` : `/${serveName}`;
2474
+ logger2.info("Starting single-file server...");
2475
+ logger2.info(`File: ${file}`);
2476
+ logger2.info(`URL: http://${host}:${port}${urlPath}`);
2477
+ try {
2478
+ const app = express();
2479
+ app.get("/health", (req, res) => {
2480
+ res.json({
2481
+ status: "ok",
2482
+ version: VERSION,
2483
+ timestamp: Date.now(),
2484
+ mode: "serve",
2485
+ file,
2486
+ url: urlPath
2487
+ });
2488
+ });
2489
+ app.get(urlPath, (req, res) => {
2490
+ res.type("application/javascript");
2491
+ res.sendFile(file, { dotfiles: "allow" }, (err) => {
2492
+ if (err && !res.headersSent) {
2493
+ const errCode = err.code;
2494
+ const errStatus = err.status || err.statusCode;
2495
+ if (errCode !== "ECONNABORTED") {
2496
+ logger2.error(
2497
+ `sendFile error for ${file}: ${err.message} (code: ${errCode}, status: ${errStatus})`
2498
+ );
2499
+ }
2500
+ if (errStatus === 404 || errCode === "ENOENT" || errCode === "EISDIR" || errCode === "ENOTDIR") {
2501
+ res.status(404).send("File not found");
2502
+ } else if (errCode !== "ECONNABORTED") {
2503
+ res.status(500).send("Internal server error");
2504
+ }
2505
+ }
2506
+ });
2507
+ });
2508
+ const server = app.listen(port, host, () => {
2509
+ logger2.info(`Server listening on http://${host}:${port}`);
2510
+ logger2.info(`GET ${urlPath} - Bundle file`);
2511
+ logger2.info(`GET /health - Health check`);
2512
+ });
2513
+ const shutdownHandler = (signal) => {
2514
+ logger2.info(`Received ${signal}, shutting down...`);
2515
+ server.close(() => {
2516
+ logger2.info("Server closed");
2517
+ process.exit(0);
2518
+ });
2519
+ };
2520
+ process.on("SIGTERM", () => shutdownHandler("SIGTERM"));
2521
+ process.on("SIGINT", () => shutdownHandler("SIGINT"));
2522
+ await new Promise(() => {
2523
+ });
2524
+ } catch (error) {
2525
+ const message = error instanceof Error ? error.message : String(error);
2526
+ logger2.error(`Server failed: ${message}`);
2527
+ process.exit(1);
2528
+ }
2529
+ }
2530
+
2531
+ // src/commands/run/execution.ts
2469
2532
  var logLevel = process.env.VERBOSE === "true" ? Level.DEBUG : Level.INFO;
2470
- var logger = createLogger2({ level: logLevel });
2533
+ var loggerConfig = { level: logLevel };
2534
+ var logger = createLogger2(loggerConfig);
2471
2535
  async function executeRunLocal(mode, flowPath, options) {
2472
2536
  switch (mode) {
2473
2537
  case "collect": {
@@ -2478,7 +2542,7 @@ async function executeRunLocal(mode, flowPath, options) {
2478
2542
  port: options.port,
2479
2543
  host: options.host
2480
2544
  };
2481
- await runFlow(flowPath, config, logger.scope("runner"));
2545
+ await runFlow(flowPath, config, logger.scope("runner"), loggerConfig);
2482
2546
  break;
2483
2547
  }
2484
2548
  case "serve": {
@@ -2513,76 +2577,40 @@ async function runCommand(mode, options) {
2513
2577
  if (mode === "collect") {
2514
2578
  if (isPreBuilt) {
2515
2579
  flowPath = path13.resolve(configPath);
2516
- if (!options.json && !options.silent) {
2517
- logger2.info(`\u{1F4E6} Using pre-built flow: ${path13.basename(flowPath)}`);
2518
- }
2580
+ logger2.debug(`Using pre-built flow: ${path13.basename(flowPath)}`);
2519
2581
  } else {
2520
- if (!options.json && !options.silent) {
2521
- logger2.info("\u{1F528} Building flow bundle...");
2522
- }
2582
+ logger2.debug("Building flow bundle");
2523
2583
  flowPath = await prepareBundleForRun(configPath, {
2524
2584
  verbose: options.verbose,
2525
2585
  silent: options.json || options.silent
2526
2586
  });
2527
- if (!options.json && !options.silent) {
2528
- logger2.success("\u2705 Bundle ready");
2529
- }
2587
+ logger2.debug("Bundle ready");
2530
2588
  }
2531
2589
  }
2532
- const executionMode = getExecutionMode(options);
2533
2590
  if (options.dryRun) {
2534
- if (executionMode === "docker") {
2535
- logger2.info(
2536
- `[DRY-RUN] Would execute in Docker: run ${mode} with runtime image`
2537
- );
2538
- } else {
2539
- logger2.info(`[DRY-RUN] Would execute locally: run ${mode}`);
2540
- }
2591
+ logger2.log(`[DRY-RUN] Would execute locally: run ${mode}`);
2541
2592
  return;
2542
2593
  }
2543
- if (executionMode === "docker") {
2544
- const dockerAvailable = await isDockerAvailable();
2545
- if (!dockerAvailable) {
2546
- throw new Error(
2547
- "Docker is not available. Please install Docker or use --local flag to execute locally."
2548
- );
2549
- }
2550
- if (!options.json && !options.silent) {
2551
- logger2.info("\u{1F433} Executing in production runtime container...");
2552
- }
2553
- await executeRunInDocker(mode, flowPath, {
2554
- port: options.port,
2555
- host: options.host,
2556
- serveName: options.serveName,
2557
- servePath: options.servePath,
2558
- silent: options.silent
2559
- });
2560
- } else {
2561
- if (!options.json && !options.silent) {
2562
- const modeLabel = mode === "collect" ? "Collector" : "Server";
2563
- logger2.info(`\u{1F5A5}\uFE0F Starting ${modeLabel} locally...`);
2564
- }
2565
- await executeRunLocal(mode, flowPath, {
2566
- port: options.port,
2567
- host: options.host,
2568
- serveName: options.serveName,
2569
- servePath: options.servePath
2570
- });
2571
- }
2594
+ const modeLabel = mode === "collect" ? "Collector" : "Server";
2595
+ logger2.log(`Starting ${modeLabel}...`);
2596
+ await executeRunLocal(mode, flowPath, {
2597
+ port: options.port,
2598
+ host: options.host,
2599
+ serveName: options.serveName,
2600
+ servePath: options.servePath
2601
+ });
2572
2602
  } catch (error) {
2573
2603
  const duration = timer.getElapsed() / 1e3;
2574
2604
  const errorMessage = getErrorMessage(error);
2575
2605
  if (options.json) {
2576
- const output = {
2606
+ logger2.json({
2577
2607
  success: false,
2578
2608
  mode,
2579
2609
  error: errorMessage,
2580
2610
  duration
2581
- };
2582
- console.log(JSON.stringify(output, null, 2));
2611
+ });
2583
2612
  } else {
2584
- logger2.error("\u274C Run failed:");
2585
- logger2.error(errorMessage);
2613
+ logger2.error(`Error: ${errorMessage}`);
2586
2614
  }
2587
2615
  process.exit(1);
2588
2616
  }
@@ -2633,30 +2661,40 @@ async function run(mode, options) {
2633
2661
 
2634
2662
  // src/commands/cache.ts
2635
2663
  import fs13 from "fs-extra";
2636
- import path14 from "path";
2637
- var CACHE_DIR = path14.join(".tmp", "cache");
2638
2664
  function registerCacheCommand(program2) {
2639
2665
  const cache = program2.command("cache").description("Manage the CLI cache");
2640
- cache.command("clear").description("Clear all cached packages and builds").option("--packages", "Clear only package cache").option("--builds", "Clear only build cache").action(async (options) => {
2666
+ cache.command("clear").description("Clear all cached packages and builds").option("--packages", "Clear only package cache").option("--builds", "Clear only build cache").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
2667
+ const logger2 = createLogger({ silent: options.silent });
2668
+ const tmpDir = options.tmpDir;
2641
2669
  if (options.packages) {
2642
- await fs13.remove(path14.join(CACHE_DIR, "packages"));
2643
- console.log("Package cache cleared");
2670
+ await fs13.remove(getTmpPath(tmpDir, "cache", "packages"));
2671
+ logger2.log("Package cache cleared");
2644
2672
  } else if (options.builds) {
2645
- await fs13.remove(path14.join(CACHE_DIR, "builds"));
2646
- console.log("Build cache cleared");
2673
+ await fs13.remove(getTmpPath(tmpDir, "cache", "builds"));
2674
+ logger2.log("Build cache cleared");
2647
2675
  } else {
2648
- await fs13.remove(CACHE_DIR);
2649
- console.log("All caches cleared");
2676
+ await fs13.remove(getTmpPath(tmpDir, "cache"));
2677
+ logger2.log("All caches cleared");
2650
2678
  }
2651
2679
  });
2652
- cache.command("info").description("Show cache statistics").action(async () => {
2653
- const packagesDir = path14.join(CACHE_DIR, "packages");
2654
- const buildsDir = path14.join(CACHE_DIR, "builds");
2680
+ cache.command("info").description("Show cache statistics").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
2681
+ const logger2 = createLogger({ silent: options.silent });
2682
+ const tmpDir = options.tmpDir;
2683
+ const packagesDir = getTmpPath(tmpDir, "cache", "packages");
2684
+ const buildsDir = getTmpPath(tmpDir, "cache", "builds");
2655
2685
  const packageCount = await countEntries(packagesDir);
2656
2686
  const buildCount = await countEntries(buildsDir);
2657
- console.log(`Cache directory: ${CACHE_DIR}`);
2658
- console.log(`Cached packages: ${packageCount}`);
2659
- console.log(`Cached builds: ${buildCount}`);
2687
+ logger2.log(`Cache directory: ${getTmpPath(tmpDir, "cache")}`);
2688
+ logger2.log(`Cached packages: ${packageCount}`);
2689
+ logger2.log(`Cached builds: ${buildCount}`);
2690
+ });
2691
+ }
2692
+ function registerCleanCommand(program2) {
2693
+ program2.command("clean").description("Clear the entire temp directory (.tmp/)").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
2694
+ const logger2 = createLogger({ silent: options.silent });
2695
+ const tmpDir = options.tmpDir || getDefaultTmpRoot();
2696
+ await fs13.remove(tmpDir);
2697
+ logger2.log(`Temp directory cleared: ${tmpDir}`);
2660
2698
  });
2661
2699
  }
2662
2700
  async function countEntries(dir) {
@@ -2671,11 +2709,10 @@ program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS
2671
2709
  program.hook("preAction", (thisCommand, actionCommand) => {
2672
2710
  const options = actionCommand.opts();
2673
2711
  if (!options.silent && !options.json) {
2674
- console.log(`\u{1F680} walkerOS CLI v${VERSION}`);
2675
- console.log(`\u{1F433} Using Docker runtime: walkeros/docker:${DOCKER_VERSION2}`);
2712
+ console.log(`${chalk2.hex("#01b5e2")("walkerOS")} v${VERSION}`);
2676
2713
  }
2677
2714
  });
2678
- program.command("bundle [file]").description("Bundle NPM packages with custom code").option("-f, --flow <name>", "flow to build (for multi-flow configs)").option("--all", "build all flows (for multi-flow configs)").option("-s, --stats", "show bundle statistics").option("--json", "output statistics in JSON format (implies --stats)").option("--no-cache", "disable package caching and download fresh packages").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) => {
2715
+ program.command("bundle [file]").description("Bundle NPM packages with custom code").option("-f, --flow <name>", "flow to build (for multi-flow configs)").option("--all", "build all flows (for multi-flow configs)").option("-s, --stats", "show bundle statistics").option("--json", "output statistics in JSON format (implies --stats)").option("--no-cache", "disable package caching and download fresh packages").option("-v, --verbose", "verbose output").option("--dry-run", "preview command without executing").option("--silent", "suppress output").option("--dockerfile", "generate Dockerfile alongside bundle").action(async (file, options) => {
2679
2716
  await bundleCommand({
2680
2717
  config: file || "bundle.config.json",
2681
2718
  flow: options.flow,
@@ -2684,21 +2721,21 @@ program.command("bundle [file]").description("Bundle NPM packages with custom co
2684
2721
  json: options.json,
2685
2722
  cache: options.cache,
2686
2723
  verbose: options.verbose,
2687
- local: options.local,
2688
2724
  dryRun: options.dryRun,
2689
- silent: options.silent
2725
+ silent: options.silent,
2726
+ dockerfile: options.dockerfile
2690
2727
  });
2691
2728
  });
2692
2729
  program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
2693
2730
  "-e, --event <source>",
2694
2731
  "Event to simulate (JSON string, file path, or URL)"
2695
- ).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) => {
2732
+ ).option("-p, --platform <platform>", "Platform override (web or server)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
2696
2733
  await simulateCommand({
2697
2734
  config: file || "bundle.config.json",
2698
2735
  event: options.event,
2736
+ platform: options.platform,
2699
2737
  json: options.json,
2700
2738
  verbose: options.verbose,
2701
- local: options.local,
2702
2739
  dryRun: options.dryRun,
2703
2740
  silent: options.silent
2704
2741
  });
@@ -2706,35 +2743,34 @@ program.command("simulate [file]").description("Simulate event processing and ca
2706
2743
  program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
2707
2744
  "-e, --event <source>",
2708
2745
  "Event to push (JSON string, file path, or URL)"
2709
- ).option("--flow <name>", "Flow name (for multi-flow configs)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("-s, --silent", "Suppress output").option("--local", "Execute in local Node.js instead of Docker").action(async (file, options) => {
2746
+ ).option("--flow <name>", "Flow name (for multi-flow configs)").option("-p, --platform <platform>", "Platform override (web or server)").option("--json", "Output results as JSON").option("-v, --verbose", "Verbose output").option("-s, --silent", "Suppress output").action(async (file, options) => {
2710
2747
  await pushCommand({
2711
2748
  config: file || "bundle.config.json",
2712
2749
  event: options.event,
2713
2750
  flow: options.flow,
2751
+ platform: options.platform,
2714
2752
  json: options.json,
2715
2753
  verbose: options.verbose,
2716
- silent: options.silent,
2717
- local: options.local
2754
+ silent: options.silent
2718
2755
  });
2719
2756
  });
2720
2757
  var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
2721
2758
  runCmd.command("collect [file]").description(
2722
2759
  "Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
2723
- ).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) => {
2760
+ ).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("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
2724
2761
  await runCommand("collect", {
2725
2762
  config: file || "server-collect.mjs",
2726
2763
  port: options.port,
2727
2764
  host: options.host,
2728
2765
  json: options.json,
2729
2766
  verbose: options.verbose,
2730
- local: options.local,
2731
2767
  dryRun: options.dryRun,
2732
2768
  silent: options.silent
2733
2769
  });
2734
2770
  });
2735
2771
  runCmd.command("serve [file]").description(
2736
2772
  "Run serve mode (single-file server for browser bundles). Defaults to baked-in web-serve.js if no file specified."
2737
- ).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) => {
2773
+ ).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("--dry-run", "preview command without executing").option("--silent", "suppress output").action(async (file, options) => {
2738
2774
  await runCommand("serve", {
2739
2775
  config: file || "web-serve.js",
2740
2776
  port: options.port,
@@ -2743,12 +2779,12 @@ runCmd.command("serve [file]").description(
2743
2779
  servePath: options.path,
2744
2780
  json: options.json,
2745
2781
  verbose: options.verbose,
2746
- local: options.local,
2747
2782
  dryRun: options.dryRun,
2748
2783
  silent: options.silent
2749
2784
  });
2750
2785
  });
2751
2786
  registerCacheCommand(program);
2787
+ registerCleanCommand(program);
2752
2788
  program.parse();
2753
2789
  export {
2754
2790
  bundle,