@walkeros/cli 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,611 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // ../../node_modules/is-docker/index.js
13
+ import fs15 from "fs";
14
+ function hasDockerEnv() {
15
+ try {
16
+ fs15.statSync("/.dockerenv");
17
+ return true;
18
+ } catch {
19
+ return false;
20
+ }
21
+ }
22
+ function hasDockerCGroup() {
23
+ try {
24
+ return fs15.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
25
+ } catch {
26
+ return false;
27
+ }
28
+ }
29
+ function isDocker() {
30
+ if (isDockerCached === void 0) {
31
+ isDockerCached = hasDockerEnv() || hasDockerCGroup();
32
+ }
33
+ return isDockerCached;
34
+ }
35
+ var isDockerCached;
36
+ var init_is_docker = __esm({
37
+ "../../node_modules/is-docker/index.js"() {
38
+ "use strict";
39
+ }
40
+ });
41
+
42
+ // ../../node_modules/is-inside-container/index.js
43
+ import fs16 from "fs";
44
+ function isInsideContainer() {
45
+ if (cachedResult === void 0) {
46
+ cachedResult = hasContainerEnv() || isDocker();
47
+ }
48
+ return cachedResult;
49
+ }
50
+ var cachedResult, hasContainerEnv;
51
+ var init_is_inside_container = __esm({
52
+ "../../node_modules/is-inside-container/index.js"() {
53
+ "use strict";
54
+ init_is_docker();
55
+ hasContainerEnv = () => {
56
+ try {
57
+ fs16.statSync("/run/.containerenv");
58
+ return true;
59
+ } catch {
60
+ return false;
61
+ }
62
+ };
63
+ }
64
+ });
65
+
66
+ // ../../node_modules/is-wsl/index.js
67
+ import process2 from "process";
68
+ import os from "os";
69
+ import fs17 from "fs";
70
+ var isWsl, is_wsl_default;
71
+ var init_is_wsl = __esm({
72
+ "../../node_modules/is-wsl/index.js"() {
73
+ "use strict";
74
+ init_is_inside_container();
75
+ isWsl = () => {
76
+ if (process2.platform !== "linux") {
77
+ return false;
78
+ }
79
+ if (os.release().toLowerCase().includes("microsoft")) {
80
+ if (isInsideContainer()) {
81
+ return false;
82
+ }
83
+ return true;
84
+ }
85
+ try {
86
+ return fs17.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
87
+ } catch {
88
+ return false;
89
+ }
90
+ };
91
+ is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
92
+ }
93
+ });
94
+
95
+ // ../../node_modules/wsl-utils/index.js
96
+ import process3 from "process";
97
+ import fs18, { constants as fsConstants } from "fs/promises";
98
+ var wslDrivesMountPoint, powerShellPathFromWsl, powerShellPath;
99
+ var init_wsl_utils = __esm({
100
+ "../../node_modules/wsl-utils/index.js"() {
101
+ "use strict";
102
+ init_is_wsl();
103
+ init_is_wsl();
104
+ wslDrivesMountPoint = /* @__PURE__ */ (() => {
105
+ const defaultMountPoint = "/mnt/";
106
+ let mountPoint;
107
+ return async function() {
108
+ if (mountPoint) {
109
+ return mountPoint;
110
+ }
111
+ const configFilePath = "/etc/wsl.conf";
112
+ let isConfigFileExists = false;
113
+ try {
114
+ await fs18.access(configFilePath, fsConstants.F_OK);
115
+ isConfigFileExists = true;
116
+ } catch {
117
+ }
118
+ if (!isConfigFileExists) {
119
+ return defaultMountPoint;
120
+ }
121
+ const configContent = await fs18.readFile(configFilePath, { encoding: "utf8" });
122
+ const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
123
+ if (!configMountPoint) {
124
+ return defaultMountPoint;
125
+ }
126
+ mountPoint = configMountPoint.groups.mountPoint.trim();
127
+ mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
128
+ return mountPoint;
129
+ };
130
+ })();
131
+ powerShellPathFromWsl = async () => {
132
+ const mountPoint = await wslDrivesMountPoint();
133
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
134
+ };
135
+ powerShellPath = async () => {
136
+ if (is_wsl_default) {
137
+ return powerShellPathFromWsl();
138
+ }
139
+ return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
140
+ };
141
+ }
142
+ });
143
+
144
+ // ../../node_modules/define-lazy-prop/index.js
145
+ function defineLazyProperty(object, propertyName, valueGetter) {
146
+ const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
147
+ Object.defineProperty(object, propertyName, {
148
+ configurable: true,
149
+ enumerable: true,
150
+ get() {
151
+ const result = valueGetter();
152
+ define(result);
153
+ return result;
154
+ },
155
+ set(value) {
156
+ define(value);
157
+ }
158
+ });
159
+ return object;
160
+ }
161
+ var init_define_lazy_prop = __esm({
162
+ "../../node_modules/define-lazy-prop/index.js"() {
163
+ "use strict";
164
+ }
165
+ });
166
+
167
+ // ../../node_modules/default-browser-id/index.js
168
+ import { promisify } from "util";
169
+ import process4 from "process";
170
+ import { execFile } from "child_process";
171
+ async function defaultBrowserId() {
172
+ if (process4.platform !== "darwin") {
173
+ throw new Error("macOS only");
174
+ }
175
+ const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
176
+ const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
177
+ const browserId = match?.groups.id ?? "com.apple.Safari";
178
+ if (browserId === "com.apple.safari") {
179
+ return "com.apple.Safari";
180
+ }
181
+ return browserId;
182
+ }
183
+ var execFileAsync;
184
+ var init_default_browser_id = __esm({
185
+ "../../node_modules/default-browser-id/index.js"() {
186
+ "use strict";
187
+ execFileAsync = promisify(execFile);
188
+ }
189
+ });
190
+
191
+ // ../../node_modules/run-applescript/index.js
192
+ import process5 from "process";
193
+ import { promisify as promisify2 } from "util";
194
+ import { execFile as execFile2, execFileSync } from "child_process";
195
+ async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
196
+ if (process5.platform !== "darwin") {
197
+ throw new Error("macOS only");
198
+ }
199
+ const outputArguments = humanReadableOutput ? [] : ["-ss"];
200
+ const execOptions = {};
201
+ if (signal) {
202
+ execOptions.signal = signal;
203
+ }
204
+ const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
205
+ return stdout.trim();
206
+ }
207
+ var execFileAsync2;
208
+ var init_run_applescript = __esm({
209
+ "../../node_modules/run-applescript/index.js"() {
210
+ "use strict";
211
+ execFileAsync2 = promisify2(execFile2);
212
+ }
213
+ });
214
+
215
+ // ../../node_modules/bundle-name/index.js
216
+ async function bundleName(bundleId) {
217
+ return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
218
+ tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
219
+ }
220
+ var init_bundle_name = __esm({
221
+ "../../node_modules/bundle-name/index.js"() {
222
+ "use strict";
223
+ init_run_applescript();
224
+ }
225
+ });
226
+
227
+ // ../../node_modules/default-browser/windows.js
228
+ import { promisify as promisify3 } from "util";
229
+ import { execFile as execFile3 } from "child_process";
230
+ async function defaultBrowser(_execFileAsync = execFileAsync3) {
231
+ const { stdout } = await _execFileAsync("reg", [
232
+ "QUERY",
233
+ " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
234
+ "/v",
235
+ "ProgId"
236
+ ]);
237
+ const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
238
+ if (!match) {
239
+ throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
240
+ }
241
+ const { id } = match.groups;
242
+ const browser = windowsBrowserProgIds[id];
243
+ if (!browser) {
244
+ throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
245
+ }
246
+ return browser;
247
+ }
248
+ var execFileAsync3, windowsBrowserProgIds, _windowsBrowserProgIdMap, UnknownBrowserError;
249
+ var init_windows = __esm({
250
+ "../../node_modules/default-browser/windows.js"() {
251
+ "use strict";
252
+ execFileAsync3 = promisify3(execFile3);
253
+ windowsBrowserProgIds = {
254
+ MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
255
+ // The missing `L` is correct.
256
+ MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
257
+ MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
258
+ AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
259
+ ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
260
+ ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
261
+ ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
262
+ ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
263
+ BraveHTML: { name: "Brave", id: "com.brave.Browser" },
264
+ BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
265
+ BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
266
+ BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
267
+ FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
268
+ OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
269
+ VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
270
+ "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
271
+ };
272
+ _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
273
+ UnknownBrowserError = class extends Error {
274
+ };
275
+ }
276
+ });
277
+
278
+ // ../../node_modules/default-browser/index.js
279
+ import { promisify as promisify4 } from "util";
280
+ import process6 from "process";
281
+ import { execFile as execFile4 } from "child_process";
282
+ async function defaultBrowser2() {
283
+ if (process6.platform === "darwin") {
284
+ const id = await defaultBrowserId();
285
+ const name = await bundleName(id);
286
+ return { name, id };
287
+ }
288
+ if (process6.platform === "linux") {
289
+ const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
290
+ const id = stdout.trim();
291
+ const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
292
+ return { name, id };
293
+ }
294
+ if (process6.platform === "win32") {
295
+ return defaultBrowser();
296
+ }
297
+ throw new Error("Only macOS, Linux, and Windows are supported");
298
+ }
299
+ var execFileAsync4, titleize;
300
+ var init_default_browser = __esm({
301
+ "../../node_modules/default-browser/index.js"() {
302
+ "use strict";
303
+ init_default_browser_id();
304
+ init_bundle_name();
305
+ init_windows();
306
+ execFileAsync4 = promisify4(execFile4);
307
+ titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
308
+ }
309
+ });
310
+
311
+ // ../../node_modules/open/index.js
312
+ var open_exports = {};
313
+ __export(open_exports, {
314
+ apps: () => apps,
315
+ default: () => open_default,
316
+ openApp: () => openApp
317
+ });
318
+ import process7 from "process";
319
+ import { Buffer as Buffer2 } from "buffer";
320
+ import path15 from "path";
321
+ import { fileURLToPath as fileURLToPath3 } from "url";
322
+ import { promisify as promisify5 } from "util";
323
+ import childProcess from "child_process";
324
+ import fs19, { constants as fsConstants2 } from "fs/promises";
325
+ async function getWindowsDefaultBrowserFromWsl() {
326
+ const powershellPath = await powerShellPath();
327
+ const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
328
+ const encodedCommand = Buffer2.from(rawCommand, "utf16le").toString("base64");
329
+ const { stdout } = await execFile5(
330
+ powershellPath,
331
+ [
332
+ "-NoProfile",
333
+ "-NonInteractive",
334
+ "-ExecutionPolicy",
335
+ "Bypass",
336
+ "-EncodedCommand",
337
+ encodedCommand
338
+ ],
339
+ { encoding: "utf8" }
340
+ );
341
+ const progId = stdout.trim();
342
+ const browserMap = {
343
+ ChromeHTML: "com.google.chrome",
344
+ BraveHTML: "com.brave.Browser",
345
+ MSEdgeHTM: "com.microsoft.edge",
346
+ FirefoxURL: "org.mozilla.firefox"
347
+ };
348
+ return browserMap[progId] ? { id: browserMap[progId] } : {};
349
+ }
350
+ function detectArchBinary(binary) {
351
+ if (typeof binary === "string" || Array.isArray(binary)) {
352
+ return binary;
353
+ }
354
+ const { [arch]: archBinary } = binary;
355
+ if (!archBinary) {
356
+ throw new Error(`${arch} is not supported`);
357
+ }
358
+ return archBinary;
359
+ }
360
+ function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
361
+ if (wsl && is_wsl_default) {
362
+ return detectArchBinary(wsl);
363
+ }
364
+ if (!platformBinary) {
365
+ throw new Error(`${platform} is not supported`);
366
+ }
367
+ return detectArchBinary(platformBinary);
368
+ }
369
+ var execFile5, __dirname, localXdgOpenPath, platform, arch, pTryEach, baseOpen, open, openApp, apps, open_default;
370
+ var init_open = __esm({
371
+ "../../node_modules/open/index.js"() {
372
+ "use strict";
373
+ init_wsl_utils();
374
+ init_define_lazy_prop();
375
+ init_default_browser();
376
+ init_is_inside_container();
377
+ execFile5 = promisify5(childProcess.execFile);
378
+ __dirname = path15.dirname(fileURLToPath3(import.meta.url));
379
+ localXdgOpenPath = path15.join(__dirname, "xdg-open");
380
+ ({ platform, arch } = process7);
381
+ pTryEach = async (array, mapper) => {
382
+ let latestError;
383
+ for (const item of array) {
384
+ try {
385
+ return await mapper(item);
386
+ } catch (error) {
387
+ latestError = error;
388
+ }
389
+ }
390
+ throw latestError;
391
+ };
392
+ baseOpen = async (options) => {
393
+ options = {
394
+ wait: false,
395
+ background: false,
396
+ newInstance: false,
397
+ allowNonzeroExitCode: false,
398
+ ...options
399
+ };
400
+ if (Array.isArray(options.app)) {
401
+ return pTryEach(options.app, (singleApp) => baseOpen({
402
+ ...options,
403
+ app: singleApp
404
+ }));
405
+ }
406
+ let { name: app, arguments: appArguments = [] } = options.app ?? {};
407
+ appArguments = [...appArguments];
408
+ if (Array.isArray(app)) {
409
+ return pTryEach(app, (appName) => baseOpen({
410
+ ...options,
411
+ app: {
412
+ name: appName,
413
+ arguments: appArguments
414
+ }
415
+ }));
416
+ }
417
+ if (app === "browser" || app === "browserPrivate") {
418
+ const ids = {
419
+ "com.google.chrome": "chrome",
420
+ "google-chrome.desktop": "chrome",
421
+ "com.brave.Browser": "brave",
422
+ "org.mozilla.firefox": "firefox",
423
+ "firefox.desktop": "firefox",
424
+ "com.microsoft.msedge": "edge",
425
+ "com.microsoft.edge": "edge",
426
+ "com.microsoft.edgemac": "edge",
427
+ "microsoft-edge.desktop": "edge"
428
+ };
429
+ const flags = {
430
+ chrome: "--incognito",
431
+ brave: "--incognito",
432
+ firefox: "--private-window",
433
+ edge: "--inPrivate"
434
+ };
435
+ const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
436
+ if (browser.id in ids) {
437
+ const browserName = ids[browser.id];
438
+ if (app === "browserPrivate") {
439
+ appArguments.push(flags[browserName]);
440
+ }
441
+ return baseOpen({
442
+ ...options,
443
+ app: {
444
+ name: apps[browserName],
445
+ arguments: appArguments
446
+ }
447
+ });
448
+ }
449
+ throw new Error(`${browser.name} is not supported as a default browser`);
450
+ }
451
+ let command;
452
+ const cliArguments = [];
453
+ const childProcessOptions = {};
454
+ if (platform === "darwin") {
455
+ command = "open";
456
+ if (options.wait) {
457
+ cliArguments.push("--wait-apps");
458
+ }
459
+ if (options.background) {
460
+ cliArguments.push("--background");
461
+ }
462
+ if (options.newInstance) {
463
+ cliArguments.push("--new");
464
+ }
465
+ if (app) {
466
+ cliArguments.push("-a", app);
467
+ }
468
+ } else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
469
+ command = await powerShellPath();
470
+ cliArguments.push(
471
+ "-NoProfile",
472
+ "-NonInteractive",
473
+ "-ExecutionPolicy",
474
+ "Bypass",
475
+ "-EncodedCommand"
476
+ );
477
+ if (!is_wsl_default) {
478
+ childProcessOptions.windowsVerbatimArguments = true;
479
+ }
480
+ const encodedArguments = ["Start"];
481
+ if (options.wait) {
482
+ encodedArguments.push("-Wait");
483
+ }
484
+ if (app) {
485
+ encodedArguments.push(`"\`"${app}\`""`);
486
+ if (options.target) {
487
+ appArguments.push(options.target);
488
+ }
489
+ } else if (options.target) {
490
+ encodedArguments.push(`"${options.target}"`);
491
+ }
492
+ if (appArguments.length > 0) {
493
+ appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
494
+ encodedArguments.push("-ArgumentList", appArguments.join(","));
495
+ }
496
+ options.target = Buffer2.from(encodedArguments.join(" "), "utf16le").toString("base64");
497
+ } else {
498
+ if (app) {
499
+ command = app;
500
+ } else {
501
+ const isBundled = !__dirname || __dirname === "/";
502
+ let exeLocalXdgOpen = false;
503
+ try {
504
+ await fs19.access(localXdgOpenPath, fsConstants2.X_OK);
505
+ exeLocalXdgOpen = true;
506
+ } catch {
507
+ }
508
+ const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
509
+ command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
510
+ }
511
+ if (appArguments.length > 0) {
512
+ cliArguments.push(...appArguments);
513
+ }
514
+ if (!options.wait) {
515
+ childProcessOptions.stdio = "ignore";
516
+ childProcessOptions.detached = true;
517
+ }
518
+ }
519
+ if (platform === "darwin" && appArguments.length > 0) {
520
+ cliArguments.push("--args", ...appArguments);
521
+ }
522
+ if (options.target) {
523
+ cliArguments.push(options.target);
524
+ }
525
+ const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
526
+ if (options.wait) {
527
+ return new Promise((resolve3, reject) => {
528
+ subprocess.once("error", reject);
529
+ subprocess.once("close", (exitCode) => {
530
+ if (!options.allowNonzeroExitCode && exitCode > 0) {
531
+ reject(new Error(`Exited with code ${exitCode}`));
532
+ return;
533
+ }
534
+ resolve3(subprocess);
535
+ });
536
+ });
537
+ }
538
+ subprocess.unref();
539
+ return subprocess;
540
+ };
541
+ open = (target, options) => {
542
+ if (typeof target !== "string") {
543
+ throw new TypeError("Expected a `target`");
544
+ }
545
+ return baseOpen({
546
+ ...options,
547
+ target
548
+ });
549
+ };
550
+ openApp = (name, options) => {
551
+ if (typeof name !== "string" && !Array.isArray(name)) {
552
+ throw new TypeError("Expected a valid `name`");
553
+ }
554
+ const { arguments: appArguments = [] } = options ?? {};
555
+ if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) {
556
+ throw new TypeError("Expected `appArguments` as Array type");
557
+ }
558
+ return baseOpen({
559
+ ...options,
560
+ app: {
561
+ name,
562
+ arguments: appArguments
563
+ }
564
+ });
565
+ };
566
+ apps = {};
567
+ defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
568
+ darwin: "google chrome",
569
+ win32: "chrome",
570
+ linux: ["google-chrome", "google-chrome-stable", "chromium"]
571
+ }, {
572
+ wsl: {
573
+ ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
574
+ x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
575
+ }
576
+ }));
577
+ defineLazyProperty(apps, "brave", () => detectPlatformBinary({
578
+ darwin: "brave browser",
579
+ win32: "brave",
580
+ linux: ["brave-browser", "brave"]
581
+ }, {
582
+ wsl: {
583
+ ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
584
+ x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
585
+ }
586
+ }));
587
+ defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
588
+ darwin: "firefox",
589
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
590
+ linux: "firefox"
591
+ }, {
592
+ wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
593
+ }));
594
+ defineLazyProperty(apps, "edge", () => detectPlatformBinary({
595
+ darwin: "microsoft edge",
596
+ win32: "msedge",
597
+ linux: ["microsoft-edge", "microsoft-edge-dev"]
598
+ }, {
599
+ wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
600
+ }));
601
+ defineLazyProperty(apps, "browser", () => "browser");
602
+ defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
603
+ open_default = open;
604
+ }
605
+ });
2
606
 
3
607
  // src/index.ts
4
608
  import { Command } from "commander";
5
- import chalk3 from "chalk";
6
609
 
7
610
  // src/version.ts
8
611
  import { readFileSync } from "fs";
@@ -27,29 +630,33 @@ function findPackageJson() {
27
630
  }
28
631
  var VERSION = JSON.parse(findPackageJson()).version;
29
632
 
30
- // src/commands/bundle/index.ts
31
- import path9 from "path";
32
- import fs8 from "fs-extra";
33
- import { getPlatform as getPlatform2 } from "@walkeros/core";
633
+ // src/core/banner.ts
634
+ import chalk2 from "chalk";
34
635
 
35
636
  // src/core/logger.ts
36
637
  import chalk from "chalk";
37
638
  var BRAND_COLOR = "#01b5e2";
38
639
  function createLogger(options = {}) {
39
- const { verbose = false, silent = false, json = false } = options;
640
+ const {
641
+ verbose = false,
642
+ silent = false,
643
+ json = false,
644
+ stderr = false
645
+ } = options;
40
646
  const shouldLog = !silent && !json;
41
647
  const shouldDebug = verbose && !silent && !json;
648
+ const out = stderr ? console.error : console.log;
42
649
  return {
43
650
  log: (...args) => {
44
651
  if (shouldLog) {
45
652
  const message = args.map((arg) => String(arg)).join(" ");
46
- console.log(message);
653
+ out(message);
47
654
  }
48
655
  },
49
656
  brand: (...args) => {
50
657
  if (shouldLog) {
51
658
  const message = args.map((arg) => String(arg)).join(" ");
52
- console.log(chalk.hex(BRAND_COLOR)(message));
659
+ out(chalk.hex(BRAND_COLOR)(message));
53
660
  }
54
661
  },
55
662
  error: (...args) => {
@@ -61,43 +668,43 @@ function createLogger(options = {}) {
61
668
  debug: (...args) => {
62
669
  if (shouldDebug) {
63
670
  const message = args.map((arg) => String(arg)).join(" ");
64
- console.log(` ${message}`);
671
+ out(` ${message}`);
65
672
  }
66
673
  },
67
674
  json: (data) => {
68
675
  if (!silent) {
69
- console.log(JSON.stringify(data, null, 2));
676
+ out(JSON.stringify(data, null, 2));
70
677
  }
71
678
  },
72
679
  // Backward-compatible methods (all use default terminal color per design)
73
680
  info: (...args) => {
74
681
  if (shouldLog) {
75
682
  const message = args.map((arg) => String(arg)).join(" ");
76
- console.log(message);
683
+ out(message);
77
684
  }
78
685
  },
79
686
  success: (...args) => {
80
687
  if (shouldLog) {
81
688
  const message = args.map((arg) => String(arg)).join(" ");
82
- console.log(message);
689
+ out(message);
83
690
  }
84
691
  },
85
692
  warning: (...args) => {
86
693
  if (shouldLog) {
87
694
  const message = args.map((arg) => String(arg)).join(" ");
88
- console.log(message);
695
+ out(message);
89
696
  }
90
697
  },
91
698
  warn: (...args) => {
92
699
  if (shouldLog) {
93
700
  const message = args.map((arg) => String(arg)).join(" ");
94
- console.log(message);
701
+ out(message);
95
702
  }
96
703
  },
97
704
  gray: (...args) => {
98
705
  if (shouldLog) {
99
706
  const message = args.map((arg) => String(arg)).join(" ");
100
- console.log(message);
707
+ out(message);
101
708
  }
102
709
  }
103
710
  };
@@ -106,10 +713,25 @@ function createCommandLogger(options) {
106
713
  return createLogger({
107
714
  verbose: options.verbose,
108
715
  silent: options.silent ?? false,
109
- json: options.json
716
+ json: options.json,
717
+ stderr: options.stderr
110
718
  });
111
719
  }
112
720
 
721
+ // src/core/banner.ts
722
+ function printBanner(version) {
723
+ const b = chalk2.hex(BRAND_COLOR);
724
+ console.error(`${b(" \u2571\u2571")}`);
725
+ console.error(`${b(" \u2571\u2571 \u2571\u2571")} ${b("walkerOS")}`);
726
+ console.error(`${b("\u2571\u2571 \u2571\u2571 \u2571\u2571")} v${version}`);
727
+ console.error("");
728
+ }
729
+
730
+ // src/commands/bundle/index.ts
731
+ import path10 from "path";
732
+ import fs9 from "fs-extra";
733
+ import { getPlatform as getPlatform2 } from "@walkeros/core";
734
+
113
735
  // src/core/collector-logger.ts
114
736
  function createCollectorLoggerConfig(cliLogger, verbose) {
115
737
  return {
@@ -152,6 +774,17 @@ function createTimer() {
152
774
  }
153
775
 
154
776
  // src/core/output.ts
777
+ import fs from "fs-extra";
778
+ import path from "path";
779
+ async function writeResult(content, options) {
780
+ if (options.output) {
781
+ const outputPath = path.resolve(options.output);
782
+ await fs.ensureDir(path.dirname(outputPath));
783
+ await fs.writeFile(outputPath, content);
784
+ } else {
785
+ process.stdout.write(content);
786
+ }
787
+ }
155
788
  function createJsonOutput(success, data, error, duration) {
156
789
  return {
157
790
  success,
@@ -171,25 +804,139 @@ function formatBytes(bytes) {
171
804
  }
172
805
 
173
806
  // src/core/tmp.ts
174
- import path from "path";
807
+ import path2 from "path";
175
808
  var DEFAULT_TMP_ROOT = ".tmp";
176
809
  function getTmpPath(tmpDir, ...segments) {
177
810
  const root = tmpDir || DEFAULT_TMP_ROOT;
178
- const absoluteRoot = path.isAbsolute(root) ? root : path.resolve(root);
179
- return path.join(absoluteRoot, ...segments);
180
- }
181
- function getDefaultTmpRoot() {
182
- return DEFAULT_TMP_ROOT;
811
+ const absoluteRoot = path2.isAbsolute(root) ? root : path2.resolve(root);
812
+ return path2.join(absoluteRoot, ...segments);
183
813
  }
184
814
 
185
815
  // src/core/asset-resolver.ts
186
816
  import { fileURLToPath as fileURLToPath2 } from "url";
187
- import { existsSync } from "fs";
817
+ import { existsSync as existsSync2 } from "fs";
818
+ import path4 from "path";
819
+
820
+ // src/config/utils.ts
821
+ import fs2 from "fs-extra";
188
822
  import path3 from "path";
189
823
 
824
+ // src/lib/config-file.ts
825
+ import {
826
+ readFileSync as readFileSync2,
827
+ writeFileSync,
828
+ mkdirSync,
829
+ unlinkSync,
830
+ existsSync
831
+ } from "fs";
832
+ import { join as join2 } from "path";
833
+ import { homedir } from "os";
834
+ function getConfigDir() {
835
+ const xdgConfig = process.env.XDG_CONFIG_HOME;
836
+ const base = xdgConfig || join2(homedir(), ".config");
837
+ return join2(base, "walkeros");
838
+ }
839
+ function getConfigPath() {
840
+ return join2(getConfigDir(), "config.json");
841
+ }
842
+ function readConfig() {
843
+ const configPath = getConfigPath();
844
+ try {
845
+ const content = readFileSync2(configPath, "utf-8");
846
+ return JSON.parse(content);
847
+ } catch {
848
+ return null;
849
+ }
850
+ }
851
+ function writeConfig(config) {
852
+ const dir = getConfigDir();
853
+ mkdirSync(dir, { recursive: true });
854
+ const configPath = getConfigPath();
855
+ writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 384 });
856
+ }
857
+ function deleteConfig() {
858
+ const configPath = getConfigPath();
859
+ if (existsSync(configPath)) {
860
+ unlinkSync(configPath);
861
+ return true;
862
+ }
863
+ return false;
864
+ }
865
+ function resolveToken() {
866
+ const envToken = process.env.WALKEROS_TOKEN;
867
+ if (envToken) return { token: envToken, source: "env" };
868
+ const config = readConfig();
869
+ if (config?.token) return { token: config.token, source: "config" };
870
+ return null;
871
+ }
872
+ function resolveAppUrl() {
873
+ const envUrl = process.env.WALKEROS_APP_URL;
874
+ if (envUrl) return envUrl;
875
+ const config = readConfig();
876
+ if (config?.appUrl) return config.appUrl;
877
+ return "https://app.walkeros.io";
878
+ }
879
+
880
+ // src/core/auth.ts
881
+ function getToken() {
882
+ const result = resolveToken();
883
+ return result?.token;
884
+ }
885
+ function getAuthHeaders() {
886
+ const token = getToken();
887
+ if (!token) return {};
888
+ return { Authorization: `Bearer ${token}` };
889
+ }
890
+ async function authenticatedFetch(url, init) {
891
+ const authHeaders = getAuthHeaders();
892
+ const existingHeaders = init?.headers instanceof Headers ? Object.fromEntries(init.headers.entries()) : Array.isArray(init?.headers) ? Object.fromEntries(init.headers) : init?.headers ?? {};
893
+ return fetch(url, {
894
+ ...init,
895
+ headers: { ...existingHeaders, ...authHeaders }
896
+ });
897
+ }
898
+ function resolveBaseUrl() {
899
+ return resolveAppUrl();
900
+ }
901
+ function requireProjectId() {
902
+ const projectId = process.env.WALKEROS_PROJECT_ID;
903
+ if (!projectId) throw new Error("WALKEROS_PROJECT_ID not set.");
904
+ return projectId;
905
+ }
906
+ async function apiRequest(path16, options) {
907
+ const token = getToken();
908
+ if (!token) throw new Error("WALKEROS_TOKEN not set.");
909
+ const baseUrl = resolveBaseUrl();
910
+ const { responseFormat, timeout = 3e4, ...fetchOptions } = options || {};
911
+ const response = await fetch(`${baseUrl}${path16}`, {
912
+ ...fetchOptions,
913
+ signal: AbortSignal.timeout(timeout),
914
+ headers: {
915
+ ...fetchOptions?.headers,
916
+ Authorization: `Bearer ${token}`,
917
+ "Content-Type": "application/json"
918
+ }
919
+ });
920
+ if (responseFormat === "raw") {
921
+ if (!response.ok) {
922
+ const body = await response.json().catch(() => ({}));
923
+ throw new Error(
924
+ body?.error?.message || `HTTP ${response.status}`
925
+ );
926
+ }
927
+ return response;
928
+ }
929
+ if (!response.ok) {
930
+ const body = await response.json().catch(() => ({}));
931
+ throw new Error(
932
+ body?.error?.message || `HTTP ${response.status}`
933
+ );
934
+ }
935
+ if (response.status === 204) return { success: true };
936
+ return response.json();
937
+ }
938
+
190
939
  // src/config/utils.ts
191
- import fs from "fs-extra";
192
- import path2 from "path";
193
940
  function isUrl(str) {
194
941
  try {
195
942
  const url = new URL(str);
@@ -203,7 +950,7 @@ async function downloadFromUrl(url) {
203
950
  throw new Error(`Invalid URL: ${url}`);
204
951
  }
205
952
  try {
206
- const response = await fetch(url);
953
+ const response = await authenticatedFetch(url);
207
954
  if (!response.ok) {
208
955
  throw new Error(
209
956
  `Failed to download ${url}: ${response.status} ${response.statusText}`
@@ -211,9 +958,9 @@ async function downloadFromUrl(url) {
211
958
  }
212
959
  const content = await response.text();
213
960
  const downloadsDir = getTmpPath(void 0, "downloads");
214
- await fs.ensureDir(downloadsDir);
215
- const tempPath = path2.join(downloadsDir, "flow.json");
216
- await fs.writeFile(tempPath, content, "utf-8");
961
+ await fs2.ensureDir(downloadsDir);
962
+ const tempPath = path3.join(downloadsDir, "flow.json");
963
+ await fs2.writeFile(tempPath, content, "utf-8");
217
964
  return tempPath;
218
965
  } catch (error) {
219
966
  if (error instanceof Error) {
@@ -229,13 +976,13 @@ async function loadJsonConfig(configPath) {
229
976
  absolutePath = await downloadFromUrl(configPath);
230
977
  isTemporary = true;
231
978
  } else {
232
- absolutePath = path2.resolve(configPath);
233
- if (!await fs.pathExists(absolutePath)) {
979
+ absolutePath = path3.resolve(configPath);
980
+ if (!await fs2.pathExists(absolutePath)) {
234
981
  throw new Error(`Configuration file not found: ${absolutePath}`);
235
982
  }
236
983
  }
237
984
  try {
238
- const rawConfig = await fs.readJson(absolutePath);
985
+ const rawConfig = await fs2.readJson(absolutePath);
239
986
  return rawConfig;
240
987
  } catch (error) {
241
988
  throw new Error(
@@ -244,7 +991,7 @@ async function loadJsonConfig(configPath) {
244
991
  } finally {
245
992
  if (isTemporary) {
246
993
  try {
247
- await fs.remove(absolutePath);
994
+ await fs2.remove(absolutePath);
248
995
  } catch {
249
996
  }
250
997
  }
@@ -266,11 +1013,11 @@ async function loadJsonFromSource(source, options) {
266
1013
  try {
267
1014
  const tempPath = await downloadFromUrl(trimmedSource);
268
1015
  try {
269
- const data = await fs.readJson(tempPath);
1016
+ const data = await fs2.readJson(tempPath);
270
1017
  return data;
271
1018
  } finally {
272
1019
  try {
273
- await fs.remove(tempPath);
1020
+ await fs2.remove(tempPath);
274
1021
  } catch {
275
1022
  }
276
1023
  }
@@ -280,10 +1027,10 @@ async function loadJsonFromSource(source, options) {
280
1027
  );
281
1028
  }
282
1029
  }
283
- const resolvedPath = path2.resolve(trimmedSource);
284
- if (await fs.pathExists(resolvedPath)) {
1030
+ const resolvedPath = path3.resolve(trimmedSource);
1031
+ if (await fs2.pathExists(resolvedPath)) {
285
1032
  try {
286
- const data = await fs.readJson(resolvedPath);
1033
+ const data = await fs2.readJson(resolvedPath);
287
1034
  return data;
288
1035
  } catch (error) {
289
1036
  throw new Error(
@@ -309,15 +1056,15 @@ var cachedAssetDir;
309
1056
  function getAssetDir() {
310
1057
  if (cachedAssetDir) return cachedAssetDir;
311
1058
  const currentFile = fileURLToPath2(import.meta.url);
312
- let dir = path3.dirname(currentFile);
313
- while (dir !== path3.dirname(dir)) {
314
- if (existsSync(path3.join(dir, "examples"))) {
1059
+ let dir = path4.dirname(currentFile);
1060
+ while (dir !== path4.dirname(dir)) {
1061
+ if (existsSync2(path4.join(dir, "examples"))) {
315
1062
  cachedAssetDir = dir;
316
1063
  return dir;
317
1064
  }
318
- dir = path3.dirname(dir);
1065
+ dir = path4.dirname(dir);
319
1066
  }
320
- cachedAssetDir = path3.dirname(currentFile);
1067
+ cachedAssetDir = path4.dirname(currentFile);
321
1068
  return cachedAssetDir;
322
1069
  }
323
1070
  function resolveAsset(assetPath, assetType, baseDir) {
@@ -326,12 +1073,12 @@ function resolveAsset(assetPath, assetType, baseDir) {
326
1073
  }
327
1074
  if (!assetPath.includes("/") && !assetPath.includes("\\")) {
328
1075
  const assetDir = getAssetDir();
329
- return path3.join(assetDir, "examples", assetPath);
1076
+ return path4.join(assetDir, "examples", assetPath);
330
1077
  }
331
- if (path3.isAbsolute(assetPath)) {
1078
+ if (path4.isAbsolute(assetPath)) {
332
1079
  return assetPath;
333
1080
  }
334
- return path3.resolve(baseDir || process.cwd(), assetPath);
1081
+ return path4.resolve(baseDir || process.cwd(), assetPath);
335
1082
  }
336
1083
 
337
1084
  // src/core/utils.ts
@@ -340,23 +1087,23 @@ function getErrorMessage(error) {
340
1087
  }
341
1088
 
342
1089
  // src/core/local-packages.ts
343
- import path4 from "path";
344
- import fs2 from "fs-extra";
1090
+ import path5 from "path";
1091
+ import fs3 from "fs-extra";
345
1092
  async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
346
- const absolutePath = path4.isAbsolute(localPath) ? localPath : path4.resolve(configDir, localPath);
347
- if (!await fs2.pathExists(absolutePath)) {
1093
+ const absolutePath = path5.isAbsolute(localPath) ? localPath : path5.resolve(configDir, localPath);
1094
+ if (!await fs3.pathExists(absolutePath)) {
348
1095
  throw new Error(
349
1096
  `Local package path not found: ${localPath} (resolved to ${absolutePath})`
350
1097
  );
351
1098
  }
352
- const pkgJsonPath = path4.join(absolutePath, "package.json");
353
- if (!await fs2.pathExists(pkgJsonPath)) {
1099
+ const pkgJsonPath = path5.join(absolutePath, "package.json");
1100
+ if (!await fs3.pathExists(pkgJsonPath)) {
354
1101
  throw new Error(
355
1102
  `No package.json found at ${absolutePath}. Is this a valid package directory?`
356
1103
  );
357
1104
  }
358
- const distPath = path4.join(absolutePath, "dist");
359
- const hasDistFolder = await fs2.pathExists(distPath);
1105
+ const distPath = path5.join(absolutePath, "dist");
1106
+ const hasDistFolder = await fs3.pathExists(distPath);
360
1107
  if (!hasDistFolder) {
361
1108
  logger2.warn(
362
1109
  `\u26A0\uFE0F ${packageName}: No dist/ folder found. Using package root.`
@@ -370,21 +1117,21 @@ async function resolveLocalPackage(packageName, localPath, configDir, logger2) {
370
1117
  };
371
1118
  }
372
1119
  async function copyLocalPackage(localPkg, targetDir, logger2) {
373
- const packageDir = path4.join(targetDir, "node_modules", localPkg.name);
374
- await fs2.ensureDir(path4.dirname(packageDir));
375
- await fs2.copy(
376
- path4.join(localPkg.absolutePath, "package.json"),
377
- path4.join(packageDir, "package.json")
1120
+ const packageDir = path5.join(targetDir, "node_modules", localPkg.name);
1121
+ await fs3.ensureDir(path5.dirname(packageDir));
1122
+ await fs3.copy(
1123
+ path5.join(localPkg.absolutePath, "package.json"),
1124
+ path5.join(packageDir, "package.json")
378
1125
  );
379
1126
  if (localPkg.hasDistFolder) {
380
- await fs2.copy(localPkg.distPath, path4.join(packageDir, "dist"));
1127
+ await fs3.copy(localPkg.distPath, path5.join(packageDir, "dist"));
381
1128
  } else {
382
- const entries = await fs2.readdir(localPkg.absolutePath);
1129
+ const entries = await fs3.readdir(localPkg.absolutePath);
383
1130
  for (const entry of entries) {
384
1131
  if (!["node_modules", ".turbo", ".git"].includes(entry)) {
385
- await fs2.copy(
386
- path4.join(localPkg.absolutePath, entry),
387
- path4.join(packageDir, entry)
1132
+ await fs3.copy(
1133
+ path5.join(localPkg.absolutePath, entry),
1134
+ path5.join(packageDir, entry)
388
1135
  );
389
1136
  }
390
1137
  }
@@ -394,15 +1141,15 @@ async function copyLocalPackage(localPkg, targetDir, logger2) {
394
1141
  }
395
1142
 
396
1143
  // src/core/input-detector.ts
397
- import fs3 from "fs-extra";
1144
+ import fs4 from "fs-extra";
398
1145
  async function detectInput(inputPath, platformOverride) {
399
1146
  const content = await loadContent(inputPath);
400
1147
  try {
401
1148
  JSON.parse(content);
402
1149
  return { type: "config", content };
403
1150
  } catch {
404
- const platform = platformOverride ?? detectPlatformFromPath(inputPath);
405
- return { type: "bundle", content, platform };
1151
+ const platform2 = platformOverride ?? detectPlatformFromPath(inputPath);
1152
+ return { type: "bundle", content, platform: platform2 };
406
1153
  }
407
1154
  }
408
1155
  function detectPlatformFromPath(inputPath) {
@@ -411,13 +1158,29 @@ function detectPlatformFromPath(inputPath) {
411
1158
  }
412
1159
  async function loadContent(inputPath) {
413
1160
  if (isUrl(inputPath)) {
414
- const response = await fetch(inputPath);
1161
+ const response = await authenticatedFetch(inputPath);
415
1162
  if (!response.ok) {
416
1163
  throw new Error(`Failed to fetch ${inputPath}: ${response.status}`);
417
1164
  }
418
1165
  return response.text();
419
1166
  }
420
- return fs3.readFile(inputPath, "utf8");
1167
+ return fs4.readFile(inputPath, "utf8");
1168
+ }
1169
+
1170
+ // src/core/stdin.ts
1171
+ function isStdinPiped() {
1172
+ return !process.stdin.isTTY;
1173
+ }
1174
+ async function readStdin() {
1175
+ const chunks = [];
1176
+ for await (const chunk of process.stdin) {
1177
+ chunks.push(chunk);
1178
+ }
1179
+ const content = Buffer.concat(chunks).toString("utf-8");
1180
+ if (!content.trim()) {
1181
+ throw new Error("No input received on stdin");
1182
+ }
1183
+ return content;
421
1184
  }
422
1185
 
423
1186
  // src/config/validators.ts
@@ -430,8 +1193,8 @@ function validateFlowSetup(data) {
430
1193
  const result = safeParseSetup(data);
431
1194
  if (!result.success) {
432
1195
  const errors = result.error.issues.map((issue) => {
433
- const path14 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
434
- return ` - ${path14}: ${issue.message}`;
1196
+ const path16 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
1197
+ return ` - ${path16}: ${issue.message}`;
435
1198
  }).join("\n");
436
1199
  throw new Error(`Invalid configuration:
437
1200
  ${errors}`);
@@ -465,16 +1228,16 @@ var DEFAULT_OUTPUT_PATHS = {
465
1228
  web: "./dist/walker.js",
466
1229
  server: "./dist/bundle.mjs"
467
1230
  };
468
- function getBuildDefaults(platform) {
469
- return platform === "web" ? WEB_BUILD_DEFAULTS : SERVER_BUILD_DEFAULTS;
1231
+ function getBuildDefaults(platform2) {
1232
+ return platform2 === "web" ? WEB_BUILD_DEFAULTS : SERVER_BUILD_DEFAULTS;
470
1233
  }
471
- function getDefaultOutput(platform) {
472
- return DEFAULT_OUTPUT_PATHS[platform];
1234
+ function getDefaultOutput(platform2) {
1235
+ return DEFAULT_OUTPUT_PATHS[platform2];
473
1236
  }
474
1237
 
475
1238
  // src/config/loader.ts
476
- import path5 from "path";
477
- import fs4 from "fs-extra";
1239
+ import path6 from "path";
1240
+ import fs5 from "fs-extra";
478
1241
  import { getFlowConfig, getPlatform } from "@walkeros/core";
479
1242
  var DEFAULT_INCLUDE_FOLDER = "./shared";
480
1243
  function loadBundleConfig(rawConfig, options) {
@@ -482,20 +1245,20 @@ function loadBundleConfig(rawConfig, options) {
482
1245
  const availableFlows = getAvailableFlows(setup);
483
1246
  const flowName = resolveFlow(setup, options.flowName, availableFlows);
484
1247
  const flowConfig = getFlowConfig(setup, flowName);
485
- const platform = getPlatform(flowConfig);
486
- if (!platform) {
1248
+ const platform2 = getPlatform(flowConfig);
1249
+ if (!platform2) {
487
1250
  throw new Error(
488
1251
  `Invalid configuration: flow "${flowName}" must have a "web" or "server" key.`
489
1252
  );
490
1253
  }
491
- const buildDefaults = getBuildDefaults(platform);
1254
+ const buildDefaults = getBuildDefaults(platform2);
492
1255
  const packages = flowConfig.packages || {};
493
- const output = options.buildOverrides?.output || getDefaultOutput(platform);
494
- const configDir = isUrl(options.configPath) ? process.cwd() : path5.dirname(options.configPath);
1256
+ const output = options.buildOverrides?.output || getDefaultOutput(platform2);
1257
+ const configDir = isUrl(options.configPath) ? process.cwd() : path6.dirname(options.configPath);
495
1258
  let includes = setup.include;
496
1259
  if (!includes) {
497
- const defaultIncludePath = path5.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
498
- if (fs4.pathExistsSync(defaultIncludePath)) {
1260
+ const defaultIncludePath = path6.resolve(configDir, DEFAULT_INCLUDE_FOLDER);
1261
+ if (fs5.pathExistsSync(defaultIncludePath)) {
499
1262
  includes = [DEFAULT_INCLUDE_FOLDER];
500
1263
  }
501
1264
  }
@@ -561,14 +1324,14 @@ async function loadFlowConfig(configPath, options) {
561
1324
 
562
1325
  // src/commands/bundle/bundler.ts
563
1326
  import esbuild from "esbuild";
564
- import path8 from "path";
565
- import fs7 from "fs-extra";
1327
+ import path9 from "path";
1328
+ import fs8 from "fs-extra";
566
1329
  import { packageNameToVariable } from "@walkeros/core";
567
1330
 
568
1331
  // src/commands/bundle/package-manager.ts
569
1332
  import pacote from "pacote";
570
- import path6 from "path";
571
- import fs5 from "fs-extra";
1333
+ import path7 from "path";
1334
+ import fs6 from "fs-extra";
572
1335
 
573
1336
  // src/core/cache-utils.ts
574
1337
  import { getHashServer } from "@walkeros/server-core";
@@ -609,16 +1372,16 @@ async function withTimeout(promise, ms, errorMessage) {
609
1372
  return Promise.race([promise, timeout]);
610
1373
  }
611
1374
  function getPackageDirectory(baseDir, packageName, version) {
612
- return path6.join(baseDir, "node_modules", packageName);
1375
+ return path7.join(baseDir, "node_modules", packageName);
613
1376
  }
614
1377
  async function getCachedPackagePath(pkg, tmpDir) {
615
1378
  const cacheDir = getTmpPath(tmpDir, "cache", "packages");
616
1379
  const cacheKey = await getPackageCacheKey(pkg.name, pkg.version);
617
- return path6.join(cacheDir, cacheKey);
1380
+ return path7.join(cacheDir, cacheKey);
618
1381
  }
619
1382
  async function isPackageCached(pkg, tmpDir) {
620
1383
  const cachedPath = await getCachedPackagePath(pkg, tmpDir);
621
- return fs5.pathExists(cachedPath);
1384
+ return fs6.pathExists(cachedPath);
622
1385
  }
623
1386
  function validateNoDuplicatePackages(packages) {
624
1387
  const packageMap = /* @__PURE__ */ new Map();
@@ -652,9 +1415,9 @@ async function resolveDependencies(pkg, packageDir, logger2, visited = /* @__PUR
652
1415
  }
653
1416
  visited.add(pkgKey);
654
1417
  try {
655
- const packageJsonPath = path6.join(packageDir, "package.json");
656
- if (await fs5.pathExists(packageJsonPath)) {
657
- const packageJson = await fs5.readJson(packageJsonPath);
1418
+ const packageJsonPath = path7.join(packageDir, "package.json");
1419
+ if (await fs6.pathExists(packageJsonPath)) {
1420
+ const packageJson = await fs6.readJson(packageJsonPath);
658
1421
  const deps = {
659
1422
  ...packageJson.dependencies,
660
1423
  ...packageJson.peerDependencies
@@ -682,7 +1445,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
682
1445
  }
683
1446
  }
684
1447
  validateNoDuplicatePackages(packages);
685
- await fs5.ensureDir(targetDir);
1448
+ await fs6.ensureDir(targetDir);
686
1449
  while (downloadQueue.length > 0) {
687
1450
  const pkg = downloadQueue.shift();
688
1451
  const pkgKey = `${pkg.name}@${pkg.version}`;
@@ -719,8 +1482,8 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
719
1482
  logger2.debug(`Downloading ${packageSpec} (cached)`);
720
1483
  }
721
1484
  try {
722
- await fs5.ensureDir(path6.dirname(packageDir));
723
- await fs5.copy(cachedPath, packageDir);
1485
+ await fs6.ensureDir(path7.dirname(packageDir));
1486
+ await fs6.copy(cachedPath, packageDir);
724
1487
  packagePaths.set(pkg.name, packageDir);
725
1488
  const deps = await resolveDependencies(pkg, packageDir, logger2);
726
1489
  for (const dep of deps) {
@@ -737,7 +1500,7 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
737
1500
  }
738
1501
  }
739
1502
  try {
740
- await fs5.ensureDir(path6.dirname(packageDir));
1503
+ await fs6.ensureDir(path7.dirname(packageDir));
741
1504
  const cacheDir = process.env.NPM_CACHE_DIR || getTmpPath(void 0, "cache", "npm");
742
1505
  await withTimeout(
743
1506
  pacote.extract(packageSpec, packageDir, {
@@ -754,15 +1517,15 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
754
1517
  `Package download timed out after ${PACKAGE_DOWNLOAD_TIMEOUT_MS / 1e3}s: ${packageSpec}`
755
1518
  );
756
1519
  if (userSpecifiedPackages.has(pkg.name)) {
757
- const pkgStats = await fs5.stat(path6.join(packageDir, "package.json"));
1520
+ const pkgStats = await fs6.stat(path7.join(packageDir, "package.json"));
758
1521
  const pkgJsonSize = pkgStats.size;
759
1522
  const sizeKB = (pkgJsonSize / 1024).toFixed(1);
760
1523
  logger2.debug(`Downloading ${packageSpec} (${sizeKB} KB)`);
761
1524
  }
762
1525
  if (useCache) {
763
1526
  try {
764
- await fs5.ensureDir(path6.dirname(cachedPath));
765
- await fs5.copy(packageDir, cachedPath);
1527
+ await fs6.ensureDir(path7.dirname(cachedPath));
1528
+ await fs6.copy(packageDir, cachedPath);
766
1529
  } catch (cacheError) {
767
1530
  }
768
1531
  }
@@ -782,26 +1545,26 @@ async function downloadPackages(packages, targetDir, logger2, useCache = true, c
782
1545
  }
783
1546
 
784
1547
  // src/core/build-cache.ts
785
- import fs6 from "fs-extra";
786
- import path7 from "path";
1548
+ import fs7 from "fs-extra";
1549
+ import path8 from "path";
787
1550
  async function getBuildCachePath(configContent, tmpDir) {
788
1551
  const cacheDir = getTmpPath(tmpDir, "cache", "builds");
789
1552
  const cacheKey = await getFlowConfigCacheKey(configContent);
790
- return path7.join(cacheDir, `${cacheKey}.js`);
1553
+ return path8.join(cacheDir, `${cacheKey}.js`);
791
1554
  }
792
1555
  async function isBuildCached(configContent, tmpDir) {
793
1556
  const cachePath = await getBuildCachePath(configContent, tmpDir);
794
- return fs6.pathExists(cachePath);
1557
+ return fs7.pathExists(cachePath);
795
1558
  }
796
1559
  async function cacheBuild(configContent, buildOutput, tmpDir) {
797
1560
  const cachePath = await getBuildCachePath(configContent, tmpDir);
798
- await fs6.ensureDir(path7.dirname(cachePath));
799
- await fs6.writeFile(cachePath, buildOutput, "utf-8");
1561
+ await fs7.ensureDir(path8.dirname(cachePath));
1562
+ await fs7.writeFile(cachePath, buildOutput, "utf-8");
800
1563
  }
801
1564
  async function getCachedBuild(configContent, tmpDir) {
802
1565
  const cachePath = await getBuildCachePath(configContent, tmpDir);
803
- if (await fs6.pathExists(cachePath)) {
804
- return await fs6.readFile(cachePath, "utf-8");
1566
+ if (await fs7.pathExists(cachePath)) {
1567
+ return await fs7.readFile(cachePath, "utf-8");
805
1568
  }
806
1569
  return null;
807
1570
  }
@@ -854,11 +1617,11 @@ function generateInlineCode(inline, config, env, chain, chainPropertyName, isDes
854
1617
  }
855
1618
  async function copyIncludes(includes, sourceDir, outputDir, logger2) {
856
1619
  for (const include of includes) {
857
- const sourcePath = path8.resolve(sourceDir, include);
858
- const folderName = path8.basename(include);
859
- const destPath = path8.join(outputDir, folderName);
860
- if (await fs7.pathExists(sourcePath)) {
861
- await fs7.copy(sourcePath, destPath);
1620
+ const sourcePath = path9.resolve(sourceDir, include);
1621
+ const folderName = path9.basename(include);
1622
+ const destPath = path9.join(outputDir, folderName);
1623
+ if (await fs8.pathExists(sourcePath)) {
1624
+ await fs8.copy(sourcePath, destPath);
862
1625
  logger2.debug(`Copied ${include} to output`);
863
1626
  } else {
864
1627
  logger2.debug(`Include folder not found: ${include}`);
@@ -927,14 +1690,14 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
927
1690
  const cachedBuild = await getCachedBuild(configContent);
928
1691
  if (cachedBuild) {
929
1692
  logger2.debug("Using cached build");
930
- const outputPath = path8.resolve(buildOptions.output);
931
- await fs7.ensureDir(path8.dirname(outputPath));
932
- await fs7.writeFile(outputPath, cachedBuild);
933
- const stats = await fs7.stat(outputPath);
1693
+ const outputPath = path9.resolve(buildOptions.output);
1694
+ await fs8.ensureDir(path9.dirname(outputPath));
1695
+ await fs8.writeFile(outputPath, cachedBuild);
1696
+ const stats = await fs8.stat(outputPath);
934
1697
  const sizeKB = (stats.size / 1024).toFixed(1);
935
1698
  logger2.log(`Output: ${outputPath} (${sizeKB} KB, cached)`);
936
1699
  if (showStats) {
937
- const stats2 = await fs7.stat(outputPath);
1700
+ const stats2 = await fs8.stat(outputPath);
938
1701
  const packageStats = Object.entries(buildOptions.packages).map(
939
1702
  ([name, pkg]) => ({
940
1703
  name: `${name}@${pkg.version || "latest"}`,
@@ -954,7 +1717,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
954
1717
  }
955
1718
  }
956
1719
  try {
957
- await fs7.ensureDir(TEMP_DIR);
1720
+ await fs8.ensureDir(TEMP_DIR);
958
1721
  const hasSourcesOrDests = Object.keys(
959
1722
  flowConfig.sources || {}
960
1723
  ).length > 0 || Object.keys(
@@ -982,8 +1745,8 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
982
1745
  );
983
1746
  for (const [pkgName, pkgPath] of packagePaths.entries()) {
984
1747
  if (pkgName.startsWith("@walkeros/")) {
985
- const pkgJsonPath = path8.join(pkgPath, "package.json");
986
- const pkgJson = await fs7.readJSON(pkgJsonPath);
1748
+ const pkgJsonPath = path9.join(pkgPath, "package.json");
1749
+ const pkgJson = await fs8.readJSON(pkgJsonPath);
987
1750
  if (!pkgJson.exports && pkgJson.module) {
988
1751
  pkgJson.exports = {
989
1752
  ".": {
@@ -991,12 +1754,12 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
991
1754
  require: pkgJson.main
992
1755
  }
993
1756
  };
994
- await fs7.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
1757
+ await fs8.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });
995
1758
  }
996
1759
  }
997
1760
  }
998
- const packageJsonPath = path8.join(TEMP_DIR, "package.json");
999
- await fs7.writeFile(
1761
+ const packageJsonPath = path9.join(TEMP_DIR, "package.json");
1762
+ await fs8.writeFile(
1000
1763
  packageJsonPath,
1001
1764
  JSON.stringify({ type: "module" }, null, 2)
1002
1765
  );
@@ -1006,13 +1769,13 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1006
1769
  buildOptions,
1007
1770
  packagePaths
1008
1771
  );
1009
- const entryPath = path8.join(TEMP_DIR, "entry.js");
1010
- await fs7.writeFile(entryPath, entryContent);
1772
+ const entryPath = path9.join(TEMP_DIR, "entry.js");
1773
+ await fs8.writeFile(entryPath, entryContent);
1011
1774
  logger2.debug(
1012
1775
  `Running esbuild (target: ${buildOptions.target || "es2018"}, format: ${buildOptions.format})`
1013
1776
  );
1014
- const outputPath = path8.resolve(buildOptions.output);
1015
- await fs7.ensureDir(path8.dirname(outputPath));
1777
+ const outputPath = path9.resolve(buildOptions.output);
1778
+ await fs8.ensureDir(path9.dirname(outputPath));
1016
1779
  const esbuildOptions = createEsbuildOptions(
1017
1780
  buildOptions,
1018
1781
  entryPath,
@@ -1031,13 +1794,13 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1031
1794
  } finally {
1032
1795
  await esbuild.stop();
1033
1796
  }
1034
- const outputStats = await fs7.stat(outputPath);
1797
+ const outputStats = await fs8.stat(outputPath);
1035
1798
  const sizeKB = (outputStats.size / 1024).toFixed(1);
1036
1799
  const buildTime = ((Date.now() - bundleStartTime) / 1e3).toFixed(1);
1037
1800
  logger2.log(`Output: ${outputPath} (${sizeKB} KB, ${buildTime}s)`);
1038
1801
  if (buildOptions.cache !== false) {
1039
1802
  const configContent = generateCacheKeyContent(flowConfig, buildOptions);
1040
- const buildOutput = await fs7.readFile(outputPath, "utf-8");
1803
+ const buildOutput = await fs8.readFile(outputPath, "utf-8");
1041
1804
  await cacheBuild(configContent, buildOutput);
1042
1805
  logger2.debug("Build cached for future use");
1043
1806
  }
@@ -1051,7 +1814,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1051
1814
  );
1052
1815
  }
1053
1816
  if (buildOptions.include && buildOptions.include.length > 0) {
1054
- const outputDir = path8.dirname(outputPath);
1817
+ const outputDir = path9.dirname(outputPath);
1055
1818
  await copyIncludes(
1056
1819
  buildOptions.include,
1057
1820
  buildOptions.configDir || process.cwd(),
@@ -1065,7 +1828,7 @@ async function bundleCore(flowConfig, buildOptions, logger2, showStats = false)
1065
1828
  }
1066
1829
  }
1067
1830
  async function collectBundleStats(outputPath, packages, startTime, entryContent) {
1068
- const stats = await fs7.stat(outputPath);
1831
+ const stats = await fs8.stat(outputPath);
1069
1832
  const totalSize = stats.size;
1070
1833
  const buildTime = Date.now() - startTime;
1071
1834
  const packageStats = Object.entries(packages).map(([name, pkg]) => {
@@ -1577,16 +2340,47 @@ Package Breakdown:`);
1577
2340
  }
1578
2341
 
1579
2342
  // src/commands/bundle/index.ts
2343
+ function resolveOutputPath(output, buildOptions) {
2344
+ const resolved = path10.resolve(output);
2345
+ const ext = path10.extname(resolved);
2346
+ if (output.endsWith("/") || output.endsWith(path10.sep) || !ext) {
2347
+ const filename = buildOptions.platform === "browser" ? "walker.js" : "bundle.mjs";
2348
+ return path10.join(resolved, filename);
2349
+ }
2350
+ return resolved;
2351
+ }
1580
2352
  async function bundleCommand(options) {
1581
2353
  const timer = createTimer();
1582
2354
  timer.start();
1583
- const logger2 = createCommandLogger(options);
2355
+ const writingToStdout = !options.output;
2356
+ const logger2 = createCommandLogger({
2357
+ ...options,
2358
+ stderr: writingToStdout
2359
+ });
1584
2360
  try {
1585
2361
  if (options.flow && options.all) {
1586
2362
  throw new Error("Cannot use both --flow and --all flags together");
1587
2363
  }
1588
- const configPath = resolveAsset(options.config, "config");
1589
- const rawConfig = await loadJsonConfig(configPath);
2364
+ if (options.all && writingToStdout) {
2365
+ throw new Error(
2366
+ "Cannot use --all without --output (multiple bundles need file output)"
2367
+ );
2368
+ }
2369
+ let rawConfig;
2370
+ let configPath;
2371
+ if (isStdinPiped() && !options.config) {
2372
+ const stdinContent = await readStdin();
2373
+ try {
2374
+ rawConfig = JSON.parse(stdinContent);
2375
+ } catch {
2376
+ throw new Error("Invalid JSON received on stdin");
2377
+ }
2378
+ configPath = path10.resolve(process.cwd(), "stdin.config.json");
2379
+ } else {
2380
+ const file = options.config || "bundle.config.json";
2381
+ configPath = resolveAsset(file, "config");
2382
+ rawConfig = await loadJsonConfig(configPath);
2383
+ }
1590
2384
  const configsToBundle = options.all ? loadAllFlows(rawConfig, { configPath, logger: logger2 }) : [
1591
2385
  loadBundleConfig(rawConfig, {
1592
2386
  configPath,
@@ -1605,11 +2399,16 @@ async function bundleCommand(options) {
1605
2399
  if (options.cache !== void 0) {
1606
2400
  buildOptions.cache = options.cache;
1607
2401
  }
1608
- const configBasename = path9.basename(configPath);
2402
+ if (options.output) {
2403
+ buildOptions.output = resolveOutputPath(options.output, buildOptions);
2404
+ } else {
2405
+ const ext = buildOptions.platform === "browser" ? ".js" : ".mjs";
2406
+ buildOptions.output = getTmpPath(void 0, "stdout-bundle" + ext);
2407
+ }
1609
2408
  if (isMultiFlow || options.all) {
1610
- logger2.log(`Bundling ${configBasename} (flow: ${flowName})...`);
2409
+ logger2.log(`Bundling flow: ${flowName}...`);
1611
2410
  } else {
1612
- logger2.log(`Bundling ${configBasename}...`);
2411
+ logger2.log("Bundling...");
1613
2412
  }
1614
2413
  const shouldCollectStats = options.stats || options.json;
1615
2414
  const stats = await bundleCore(
@@ -1618,29 +2417,25 @@ async function bundleCommand(options) {
1618
2417
  logger2,
1619
2418
  shouldCollectStats
1620
2419
  );
1621
- results.push({
1622
- flowName,
1623
- success: true,
1624
- stats
1625
- });
2420
+ results.push({ flowName, success: true, stats });
1626
2421
  if (!options.json && !options.all && options.stats && stats) {
1627
2422
  displayStats(stats, logger2);
1628
2423
  }
1629
- if (options.dockerfile && !options.all) {
1630
- const platform = getPlatform2(flowConfig);
1631
- if (platform) {
1632
- const outputDir = path9.dirname(buildOptions.output);
2424
+ if (writingToStdout && !options.json) {
2425
+ const bundleContent = await fs9.readFile(buildOptions.output);
2426
+ await writeResult(bundleContent, {});
2427
+ }
2428
+ if (options.dockerfile && options.output) {
2429
+ const platform2 = getPlatform2(flowConfig);
2430
+ if (platform2) {
2431
+ const outputDir = path10.dirname(buildOptions.output);
1633
2432
  const customFile = typeof options.dockerfile === "string" ? options.dockerfile : void 0;
1634
- await generateDockerfile(outputDir, platform, logger2, customFile);
2433
+ await generateDockerfile(outputDir, platform2, logger2, customFile);
1635
2434
  }
1636
2435
  }
1637
2436
  } catch (error) {
1638
2437
  const errorMessage = getErrorMessage(error);
1639
- results.push({
1640
- flowName,
1641
- success: false,
1642
- error: errorMessage
1643
- });
2438
+ results.push({ flowName, success: false, error: errorMessage });
1644
2439
  if (!options.all) {
1645
2440
  throw error;
1646
2441
  }
@@ -1650,7 +2445,7 @@ async function bundleCommand(options) {
1650
2445
  const successCount = results.filter((r) => r.success).length;
1651
2446
  const failureCount = results.filter((r) => !r.success).length;
1652
2447
  if (options.json) {
1653
- const output = failureCount === 0 ? createSuccessOutput(
2448
+ const jsonResult = failureCount === 0 ? createSuccessOutput(
1654
2449
  {
1655
2450
  flows: results,
1656
2451
  summary: {
@@ -1664,7 +2459,9 @@ async function bundleCommand(options) {
1664
2459
  `${failureCount} flow(s) failed to build`,
1665
2460
  duration
1666
2461
  );
1667
- logger2.json(output);
2462
+ await writeResult(JSON.stringify(jsonResult, null, 2) + "\n", {
2463
+ output: options.output
2464
+ });
1668
2465
  } else {
1669
2466
  if (options.all) {
1670
2467
  logger2.log(
@@ -1684,8 +2481,10 @@ Build Summary: ${successCount}/${results.length} succeeded`
1684
2481
  const duration = timer.getElapsed() / 1e3;
1685
2482
  const errorMessage = getErrorMessage(error);
1686
2483
  if (options.json) {
1687
- const output = createErrorOutput(errorMessage, duration);
1688
- logger2.json(output);
2484
+ const jsonError = createErrorOutput(errorMessage, duration);
2485
+ await writeResult(JSON.stringify(jsonError, null, 2) + "\n", {
2486
+ output: options.output
2487
+ });
1689
2488
  } else {
1690
2489
  logger2.error(`Error: ${errorMessage}`);
1691
2490
  }
@@ -1694,7 +2493,7 @@ Build Summary: ${successCount}/${results.length} succeeded`
1694
2493
  }
1695
2494
  async function bundle(configOrPath, options = {}) {
1696
2495
  let rawConfig;
1697
- let configPath = path9.resolve(process.cwd(), "walkeros.config.json");
2496
+ let configPath = path10.resolve(process.cwd(), "walkeros.config.json");
1698
2497
  if (typeof configOrPath === "string") {
1699
2498
  configPath = resolveAsset(configOrPath, "config");
1700
2499
  rawConfig = await loadJsonConfig(configPath);
@@ -1717,14 +2516,14 @@ async function bundle(configOrPath, options = {}) {
1717
2516
  options.stats ?? false
1718
2517
  );
1719
2518
  }
1720
- async function generateDockerfile(outputDir, platform, logger2, customFile) {
1721
- const destPath = path9.join(outputDir, "Dockerfile");
1722
- if (customFile && await fs8.pathExists(customFile)) {
1723
- await fs8.copy(customFile, destPath);
2519
+ async function generateDockerfile(outputDir, platform2, logger2, customFile) {
2520
+ const destPath = path10.join(outputDir, "Dockerfile");
2521
+ if (customFile && await fs9.pathExists(customFile)) {
2522
+ await fs9.copy(customFile, destPath);
1724
2523
  logger2.log(`Dockerfile: ${destPath} (copied from ${customFile})`);
1725
2524
  return;
1726
2525
  }
1727
- const isWeb = platform === "web";
2526
+ const isWeb = platform2 === "web";
1728
2527
  const bundleFile = isWeb ? "walker.js" : "bundle.mjs";
1729
2528
  const mode = isWeb ? "serve" : "collect";
1730
2529
  const dockerfile = `# Generated by walkeros CLI
@@ -1737,13 +2536,13 @@ ENV BUNDLE=/app/flow/${bundleFile}
1737
2536
 
1738
2537
  EXPOSE 8080
1739
2538
  `;
1740
- await fs8.writeFile(destPath, dockerfile);
2539
+ await fs9.writeFile(destPath, dockerfile);
1741
2540
  logger2.log(`Dockerfile: ${destPath}`);
1742
2541
  }
1743
2542
 
1744
2543
  // src/commands/simulate/simulator.ts
1745
- import path10 from "path";
1746
- import fs10 from "fs-extra";
2544
+ import path11 from "path";
2545
+ import fs11 from "fs-extra";
1747
2546
  import { getPlatform as getPlatform3 } from "@walkeros/core";
1748
2547
 
1749
2548
  // src/commands/simulate/tracker.ts
@@ -1780,9 +2579,9 @@ var CallTracker = class {
1780
2579
  }
1781
2580
  for (const fullPath of paths) {
1782
2581
  const [destKey, ...pathParts] = fullPath.split(":");
1783
- const path14 = pathParts.join(":");
1784
- if (!path14) continue;
1785
- const cleanPath = path14.replace(/^call:/, "");
2582
+ const path16 = pathParts.join(":");
2583
+ if (!path16) continue;
2584
+ const cleanPath = path16.replace(/^call:/, "");
1786
2585
  const parts = cleanPath.split(".");
1787
2586
  let current = wrapped;
1788
2587
  let source = env;
@@ -1826,7 +2625,7 @@ var CallTracker = class {
1826
2625
 
1827
2626
  // src/commands/simulate/jsdom-executor.ts
1828
2627
  import { JSDOM, VirtualConsole } from "jsdom";
1829
- import fs9 from "fs-extra";
2628
+ import fs10 from "fs-extra";
1830
2629
  function buildSandboxFromEnvs(envs, destinations, tracker) {
1831
2630
  const baseBrowserMocks = {
1832
2631
  Image: class MockImage {
@@ -1895,7 +2694,7 @@ async function executeInJSDOM(bundlePath, destinations, event, tracker, envs, ti
1895
2694
  const sandbox = buildSandboxFromEnvs(envs, destinations, tracker);
1896
2695
  Object.assign(window, sandbox.window);
1897
2696
  Object.assign(window.document, sandbox.document);
1898
- const bundleCode = await fs9.readFile(bundlePath, "utf8");
2697
+ const bundleCode = await fs10.readFile(bundlePath, "utf8");
1899
2698
  try {
1900
2699
  window.eval(bundleCode);
1901
2700
  } catch (error) {
@@ -2089,7 +2888,7 @@ async function executeSimulation(event, inputPath, platformOverride, options = {
2089
2888
  const tempDir = getTmpPath();
2090
2889
  const collectorLoggerConfig = options.logger ? createCollectorLoggerConfig(options.logger, options.verbose) : void 0;
2091
2890
  try {
2092
- await fs10.ensureDir(tempDir);
2891
+ await fs11.ensureDir(tempDir);
2093
2892
  const detected = await detectInput(inputPath, platformOverride);
2094
2893
  if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
2095
2894
  throw new Error(
@@ -2126,7 +2925,7 @@ async function executeSimulation(event, inputPath, platformOverride, options = {
2126
2925
  };
2127
2926
  } finally {
2128
2927
  if (tempDir) {
2129
- await fs10.remove(tempDir).catch(() => {
2928
+ await fs11.remove(tempDir).catch(() => {
2130
2929
  });
2131
2930
  }
2132
2931
  }
@@ -2135,11 +2934,11 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
2135
2934
  const { flowConfig, buildOptions } = await loadFlowConfig(configPath, {
2136
2935
  flowName
2137
2936
  });
2138
- const platform = getPlatform3(flowConfig);
2937
+ const platform2 = getPlatform3(flowConfig);
2139
2938
  const tracker = new CallTracker();
2140
- const tempOutput = path10.join(
2939
+ const tempOutput = path11.join(
2141
2940
  tempDir,
2142
- `simulation-bundle-${generateId()}.${platform === "web" ? "js" : "mjs"}`
2941
+ `simulation-bundle-${generateId()}.${platform2 === "web" ? "js" : "mjs"}`
2143
2942
  );
2144
2943
  const destinations = flowConfig.destinations;
2145
2944
  const simulationBuildOptions = {
@@ -2147,7 +2946,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
2147
2946
  code: buildOptions.code || "",
2148
2947
  output: tempOutput,
2149
2948
  tempDir,
2150
- ...platform === "web" ? {
2949
+ ...platform2 === "web" ? {
2151
2950
  format: "iife",
2152
2951
  platform: "browser",
2153
2952
  windowCollector: "collector",
@@ -2165,7 +2964,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
2165
2964
  );
2166
2965
  const envs = await loadDestinationEnvs(destinations || {});
2167
2966
  let result;
2168
- if (platform === "web") {
2967
+ if (platform2 === "web") {
2169
2968
  result = await executeInJSDOM(
2170
2969
  tempOutput,
2171
2970
  destinations || {},
@@ -2194,15 +2993,15 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
2194
2993
  logs: []
2195
2994
  };
2196
2995
  }
2197
- async function executeBundleSimulation(bundleContent, platform, typedEvent, tempDir, startTime, loggerConfig2) {
2198
- const tempOutput = path10.join(
2996
+ async function executeBundleSimulation(bundleContent, platform2, typedEvent, tempDir, startTime, loggerConfig2) {
2997
+ const tempOutput = path11.join(
2199
2998
  tempDir,
2200
- `bundle-${generateId()}.${platform === "server" ? "mjs" : "js"}`
2999
+ `bundle-${generateId()}.${platform2 === "server" ? "mjs" : "js"}`
2201
3000
  );
2202
- await fs10.writeFile(tempOutput, bundleContent, "utf8");
3001
+ await fs11.writeFile(tempOutput, bundleContent, "utf8");
2203
3002
  const tracker = new CallTracker();
2204
3003
  let result;
2205
- if (platform === "web") {
3004
+ if (platform2 === "web") {
2206
3005
  result = await executeInJSDOM(
2207
3006
  tempOutput,
2208
3007
  {},
@@ -2234,13 +3033,25 @@ async function executeBundleSimulation(bundleContent, platform, typedEvent, temp
2234
3033
 
2235
3034
  // src/commands/simulate/index.ts
2236
3035
  async function simulateCommand(options) {
2237
- const logger2 = createCommandLogger(options);
3036
+ const logger2 = createCommandLogger({ ...options, stderr: true });
2238
3037
  const startTime = Date.now();
2239
3038
  try {
3039
+ let config;
3040
+ if (isStdinPiped() && !options.config) {
3041
+ const stdinContent = await readStdin();
3042
+ const fs20 = await import("fs-extra");
3043
+ const path16 = await import("path");
3044
+ const tmpPath = path16.default.resolve(".tmp", "stdin-simulate.json");
3045
+ await fs20.default.ensureDir(path16.default.dirname(tmpPath));
3046
+ await fs20.default.writeFile(tmpPath, stdinContent, "utf-8");
3047
+ config = tmpPath;
3048
+ } else {
3049
+ config = options.config || "bundle.config.json";
3050
+ }
2240
3051
  const event = await loadJsonFromSource(options.event, {
2241
3052
  name: "event"
2242
3053
  });
2243
- const result = await simulateCore(options.config, event, {
3054
+ const result = await simulateCore(config, event, {
2244
3055
  flow: options.flow,
2245
3056
  json: options.json,
2246
3057
  verbose: options.verbose,
@@ -2250,23 +3061,24 @@ async function simulateCommand(options) {
2250
3061
  ...result,
2251
3062
  duration: (Date.now() - startTime) / 1e3
2252
3063
  };
2253
- const output = formatSimulationResult(resultWithDuration, {
3064
+ const formatted = formatSimulationResult(resultWithDuration, {
2254
3065
  json: options.json
2255
3066
  });
2256
- if (options.json) {
2257
- console.log(output);
2258
- } else {
2259
- logger2.log(output);
2260
- }
3067
+ await writeResult(formatted + "\n", { output: options.output });
2261
3068
  process.exit(result.success ? 0 : 1);
2262
3069
  } catch (error) {
2263
3070
  const errorMessage = getErrorMessage(error);
2264
3071
  if (options.json) {
2265
- logger2.json({
2266
- success: false,
2267
- error: errorMessage,
2268
- duration: (Date.now() - startTime) / 1e3
2269
- });
3072
+ const errorOutput = JSON.stringify(
3073
+ {
3074
+ success: false,
3075
+ error: errorMessage,
3076
+ duration: (Date.now() - startTime) / 1e3
3077
+ },
3078
+ null,
3079
+ 2
3080
+ );
3081
+ await writeResult(errorOutput + "\n", { output: options.output });
2270
3082
  } else {
2271
3083
  logger2.error(`Error: ${errorMessage}`);
2272
3084
  }
@@ -2281,28 +3093,33 @@ async function simulate(configOrPath, event, options = {}) {
2281
3093
  }
2282
3094
  return await simulateCore(configOrPath, event, {
2283
3095
  json: options.json ?? false,
2284
- verbose: options.verbose ?? false
3096
+ verbose: options.verbose ?? false,
3097
+ flow: options.flow,
3098
+ platform: options.platform
2285
3099
  });
2286
3100
  }
2287
3101
 
2288
3102
  // src/commands/push/index.ts
2289
- import path11 from "path";
3103
+ import path12 from "path";
2290
3104
  import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
2291
- import fs11 from "fs-extra";
3105
+ import fs12 from "fs-extra";
2292
3106
  import {
2293
3107
  getPlatform as getPlatform4
2294
3108
  } from "@walkeros/core";
2295
3109
  import { schemas as schemas2 } from "@walkeros/core/dev";
2296
- async function pushCommand(options) {
2297
- const logger2 = createCommandLogger(options);
3110
+ async function pushCore(inputPath, event, options = {}) {
3111
+ const logger2 = createCommandLogger({
3112
+ silent: options.silent,
3113
+ verbose: options.verbose
3114
+ });
2298
3115
  const startTime = Date.now();
2299
3116
  let tempDir;
2300
3117
  try {
2301
- logger2.debug("Loading event");
2302
- const event = await loadJsonFromSource(options.event, {
2303
- name: "event"
2304
- });
2305
- const eventResult = schemas2.PartialEventSchema.safeParse(event);
3118
+ let loadedEvent = event;
3119
+ if (typeof event === "string") {
3120
+ loadedEvent = await loadJsonFromSource(event, { name: "event" });
3121
+ }
3122
+ const eventResult = schemas2.PartialEventSchema.safeParse(loadedEvent);
2306
3123
  if (!eventResult.success) {
2307
3124
  const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
2308
3125
  throw new Error(`Invalid event: ${errors}`);
@@ -2321,11 +3138,18 @@ async function pushCommand(options) {
2321
3138
  );
2322
3139
  }
2323
3140
  logger2.debug("Detecting input type");
2324
- const detected = await detectInput(options.config, options.platform);
3141
+ const detected = await detectInput(
3142
+ inputPath,
3143
+ options.platform
3144
+ );
2325
3145
  let result;
2326
3146
  if (detected.type === "config") {
2327
3147
  result = await executeConfigPush(
2328
- options,
3148
+ {
3149
+ config: inputPath,
3150
+ flow: options.flow,
3151
+ verbose: options.verbose
3152
+ },
2329
3153
  validatedEvent,
2330
3154
  logger2,
2331
3155
  (dir) => {
@@ -2348,91 +3172,140 @@ async function pushCommand(options) {
2348
3172
  { logger: collectorLoggerConfig }
2349
3173
  );
2350
3174
  }
3175
+ return result;
3176
+ } catch (error) {
3177
+ return {
3178
+ success: false,
3179
+ duration: Date.now() - startTime,
3180
+ error: getErrorMessage(error)
3181
+ };
3182
+ } finally {
3183
+ if (tempDir) {
3184
+ await fs12.remove(tempDir).catch(() => {
3185
+ });
3186
+ }
3187
+ }
3188
+ }
3189
+ async function pushCommand(options) {
3190
+ const logger2 = createCommandLogger({ ...options, stderr: true });
3191
+ const startTime = Date.now();
3192
+ try {
3193
+ let config;
3194
+ if (isStdinPiped() && !options.config) {
3195
+ const stdinContent = await readStdin();
3196
+ const tmpPath = path12.resolve(".tmp", "stdin-push.json");
3197
+ await fs12.ensureDir(path12.dirname(tmpPath));
3198
+ await fs12.writeFile(tmpPath, stdinContent, "utf-8");
3199
+ config = tmpPath;
3200
+ } else {
3201
+ config = options.config || "bundle.config.json";
3202
+ }
3203
+ const event = await loadJsonFromSource(options.event, { name: "event" });
3204
+ const result = await pushCore(config, event, {
3205
+ flow: options.flow,
3206
+ json: options.json,
3207
+ verbose: options.verbose,
3208
+ silent: options.silent,
3209
+ platform: options.platform
3210
+ });
2351
3211
  const duration = Date.now() - startTime;
3212
+ let output;
2352
3213
  if (options.json) {
2353
- logger2.json({
2354
- success: result.success,
2355
- event: result.elbResult,
2356
- duration
2357
- });
3214
+ output = JSON.stringify(
3215
+ {
3216
+ success: result.success,
3217
+ event: result.elbResult,
3218
+ duration
3219
+ },
3220
+ null,
3221
+ 2
3222
+ );
2358
3223
  } else {
3224
+ const lines = [];
2359
3225
  if (result.success) {
2360
- logger2.log("Event pushed successfully");
3226
+ lines.push("Event pushed successfully");
2361
3227
  if (result.elbResult && typeof result.elbResult === "object") {
2362
3228
  const pushResult = result.elbResult;
2363
- if ("id" in pushResult && pushResult.id) {
2364
- logger2.log(` Event ID: ${pushResult.id}`);
2365
- }
2366
- if ("entity" in pushResult && pushResult.entity) {
2367
- logger2.log(` Entity: ${pushResult.entity}`);
2368
- }
2369
- if ("action" in pushResult && pushResult.action) {
2370
- logger2.log(` Action: ${pushResult.action}`);
2371
- }
3229
+ if ("id" in pushResult && pushResult.id)
3230
+ lines.push(` Event ID: ${pushResult.id}`);
3231
+ if ("entity" in pushResult && pushResult.entity)
3232
+ lines.push(` Entity: ${pushResult.entity}`);
3233
+ if ("action" in pushResult && pushResult.action)
3234
+ lines.push(` Action: ${pushResult.action}`);
2372
3235
  }
2373
- logger2.log(` Duration: ${duration}ms`);
3236
+ lines.push(` Duration: ${duration}ms`);
2374
3237
  } else {
2375
- logger2.error(`Error: ${result.error}`);
2376
- process.exit(1);
3238
+ lines.push(`Error: ${result.error}`);
2377
3239
  }
3240
+ output = lines.join("\n");
2378
3241
  }
2379
- process.exit(0);
3242
+ await writeResult(output + "\n", { output: options.output });
3243
+ process.exit(result.success ? 0 : 1);
2380
3244
  } catch (error) {
2381
3245
  const duration = Date.now() - startTime;
2382
3246
  const errorMessage = getErrorMessage(error);
2383
3247
  if (options.json) {
2384
- logger2.json({
2385
- success: false,
2386
- error: errorMessage,
2387
- duration
2388
- });
3248
+ const errorOutput = JSON.stringify(
3249
+ { success: false, error: errorMessage, duration },
3250
+ null,
3251
+ 2
3252
+ );
3253
+ await writeResult(errorOutput + "\n", { output: options.output });
2389
3254
  } else {
2390
3255
  logger2.error(`Error: ${errorMessage}`);
2391
3256
  }
2392
3257
  process.exit(1);
2393
- } finally {
2394
- if (tempDir) {
2395
- await fs11.remove(tempDir).catch(() => {
2396
- });
2397
- }
2398
3258
  }
2399
3259
  }
3260
+ async function push(configOrPath, event, options = {}) {
3261
+ if (typeof configOrPath !== "string") {
3262
+ throw new Error(
3263
+ "push() currently only supports config file paths. Config object support will be added in a future version. Please provide a path to a configuration file."
3264
+ );
3265
+ }
3266
+ return await pushCore(configOrPath, event, {
3267
+ json: options.json ?? false,
3268
+ verbose: options.verbose ?? false,
3269
+ flow: options.flow,
3270
+ platform: options.platform
3271
+ });
3272
+ }
2400
3273
  async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
2401
3274
  logger2.debug("Loading flow configuration");
2402
3275
  const { flowConfig, buildOptions } = await loadFlowConfig(options.config, {
2403
3276
  flowName: options.flow,
2404
3277
  logger: logger2
2405
3278
  });
2406
- const platform = getPlatform4(flowConfig);
3279
+ const platform2 = getPlatform4(flowConfig);
2407
3280
  logger2.debug("Bundling flow configuration");
2408
3281
  const configDir = buildOptions.configDir || process.cwd();
2409
- const tempDir = path11.join(
3282
+ const tempDir = path12.join(
2410
3283
  configDir,
2411
3284
  ".tmp",
2412
3285
  `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
2413
3286
  );
2414
3287
  setTempDir(tempDir);
2415
- await fs11.ensureDir(tempDir);
2416
- const tempPath = path11.join(
3288
+ await fs12.ensureDir(tempDir);
3289
+ const tempPath = path12.join(
2417
3290
  tempDir,
2418
- `bundle.${platform === "web" ? "js" : "mjs"}`
3291
+ `bundle.${platform2 === "web" ? "js" : "mjs"}`
2419
3292
  );
2420
3293
  const pushBuildOptions = {
2421
3294
  ...buildOptions,
2422
3295
  output: tempPath,
2423
- format: platform === "web" ? "iife" : "esm",
2424
- platform: platform === "web" ? "browser" : "node",
2425
- ...platform === "web" && {
3296
+ format: platform2 === "web" ? "iife" : "esm",
3297
+ platform: platform2 === "web" ? "browser" : "node",
3298
+ ...platform2 === "web" && {
2426
3299
  windowCollector: "collector",
2427
3300
  windowElb: "elb"
2428
3301
  }
2429
3302
  };
2430
3303
  await bundleCore(flowConfig, pushBuildOptions, logger2, false);
2431
3304
  logger2.debug(`Bundle created: ${tempPath}`);
2432
- if (platform === "web") {
3305
+ if (platform2 === "web") {
2433
3306
  logger2.debug("Executing in web environment (JSDOM)");
2434
3307
  return executeWebPush(tempPath, validatedEvent, logger2);
2435
- } else if (platform === "server") {
3308
+ } else if (platform2 === "server") {
2436
3309
  logger2.debug("Executing in server environment (Node.js)");
2437
3310
  const collectorLoggerConfig = createCollectorLoggerConfig(
2438
3311
  logger2,
@@ -2442,24 +3315,24 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
2442
3315
  logger: collectorLoggerConfig
2443
3316
  });
2444
3317
  } else {
2445
- throw new Error(`Unsupported platform: ${platform}`);
3318
+ throw new Error(`Unsupported platform: ${platform2}`);
2446
3319
  }
2447
3320
  }
2448
- async function executeBundlePush(bundleContent, platform, validatedEvent, logger2, setTempDir, context = {}) {
2449
- const tempDir = path11.join(
3321
+ async function executeBundlePush(bundleContent, platform2, validatedEvent, logger2, setTempDir, context = {}) {
3322
+ const tempDir = path12.join(
2450
3323
  process.cwd(),
2451
3324
  ".tmp",
2452
3325
  `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
2453
3326
  );
2454
3327
  setTempDir(tempDir);
2455
- await fs11.ensureDir(tempDir);
2456
- const tempPath = path11.join(
3328
+ await fs12.ensureDir(tempDir);
3329
+ const tempPath = path12.join(
2457
3330
  tempDir,
2458
- `bundle.${platform === "server" ? "mjs" : "js"}`
3331
+ `bundle.${platform2 === "server" ? "mjs" : "js"}`
2459
3332
  );
2460
- await fs11.writeFile(tempPath, bundleContent, "utf8");
3333
+ await fs12.writeFile(tempPath, bundleContent, "utf8");
2461
3334
  logger2.debug(`Bundle written to: ${tempPath}`);
2462
- if (platform === "web") {
3335
+ if (platform2 === "web") {
2463
3336
  logger2.debug("Executing in web environment (JSDOM)");
2464
3337
  return executeWebPush(tempPath, validatedEvent, logger2);
2465
3338
  } else {
@@ -2479,7 +3352,7 @@ async function executeWebPush(bundlePath, event, logger2) {
2479
3352
  });
2480
3353
  const { window } = dom;
2481
3354
  logger2.debug("Loading bundle...");
2482
- const bundleCode = await fs11.readFile(bundlePath, "utf8");
3355
+ const bundleCode = await fs12.readFile(bundlePath, "utf8");
2483
3356
  window.eval(bundleCode);
2484
3357
  logger2.debug("Waiting for collector...");
2485
3358
  await waitForWindowProperty2(
@@ -2571,10 +3444,10 @@ function waitForWindowProperty2(window, prop, timeout = 5e3) {
2571
3444
  }
2572
3445
 
2573
3446
  // src/commands/run/index.ts
2574
- import path13 from "path";
3447
+ import path14 from "path";
2575
3448
 
2576
3449
  // src/commands/run/validators.ts
2577
- import { existsSync as existsSync2 } from "fs";
3450
+ import { existsSync as existsSync3 } from "fs";
2578
3451
 
2579
3452
  // src/schemas/primitives.ts
2580
3453
  import { z } from "@walkeros/core/dev";
@@ -2591,6 +3464,69 @@ var RunOptionsSchema = z2.object({
2591
3464
  flowName: z2.string().optional().describe("Specific flow name to run")
2592
3465
  });
2593
3466
 
3467
+ // src/schemas/validate.ts
3468
+ import { z as z3 } from "@walkeros/core/dev";
3469
+ var ValidationTypeSchema = z3.enum(["event", "flow", "mapping"]).describe("Type of validation to perform");
3470
+ var ValidateOptionsSchema = z3.object({
3471
+ flow: z3.string().optional().describe("Flow name for multi-flow configs")
3472
+ });
3473
+ var ValidateInputShape = {
3474
+ type: ValidationTypeSchema,
3475
+ input: z3.string().min(1).describe("JSON string, file path, or URL to validate"),
3476
+ flow: z3.string().optional().describe("Flow name for multi-flow configs")
3477
+ };
3478
+ var ValidateInputSchema = z3.object(ValidateInputShape);
3479
+
3480
+ // src/schemas/bundle.ts
3481
+ import { z as z4 } from "@walkeros/core/dev";
3482
+ var BundleOptionsSchema = z4.object({
3483
+ silent: z4.boolean().optional().describe("Suppress all output"),
3484
+ verbose: z4.boolean().optional().describe("Enable verbose logging"),
3485
+ stats: z4.boolean().optional().default(true).describe("Return bundle statistics"),
3486
+ cache: z4.boolean().optional().default(true).describe("Enable package caching"),
3487
+ flowName: z4.string().optional().describe("Flow name for multi-flow configs")
3488
+ });
3489
+ var BundleInputShape = {
3490
+ configPath: FilePathSchema.describe(
3491
+ "Path to flow configuration file (JSON or JavaScript)"
3492
+ ),
3493
+ flow: z4.string().optional().describe("Flow name for multi-flow configs"),
3494
+ stats: z4.boolean().optional().default(true).describe("Return bundle statistics"),
3495
+ output: z4.string().optional().describe("Output file path (defaults to config-defined)")
3496
+ };
3497
+ var BundleInputSchema = z4.object(BundleInputShape);
3498
+
3499
+ // src/schemas/simulate.ts
3500
+ import { z as z5 } from "@walkeros/core/dev";
3501
+ var PlatformSchema = z5.enum(["web", "server"]).describe("Platform type for event processing");
3502
+ var SimulateOptionsSchema = z5.object({
3503
+ silent: z5.boolean().optional().describe("Suppress all output"),
3504
+ verbose: z5.boolean().optional().describe("Enable verbose logging"),
3505
+ json: z5.boolean().optional().describe("Format output as JSON")
3506
+ });
3507
+ var SimulateInputShape = {
3508
+ configPath: FilePathSchema.describe("Path to flow configuration file"),
3509
+ event: z5.string().min(1).describe("Event as JSON string, file path, or URL"),
3510
+ flow: z5.string().optional().describe("Flow name for multi-flow configs"),
3511
+ platform: PlatformSchema.optional().describe("Override platform detection")
3512
+ };
3513
+ var SimulateInputSchema = z5.object(SimulateInputShape);
3514
+
3515
+ // src/schemas/push.ts
3516
+ import { z as z6 } from "@walkeros/core/dev";
3517
+ var PushOptionsSchema = z6.object({
3518
+ silent: z6.boolean().optional().describe("Suppress all output"),
3519
+ verbose: z6.boolean().optional().describe("Enable verbose logging"),
3520
+ json: z6.boolean().optional().describe("Format output as JSON")
3521
+ });
3522
+ var PushInputShape = {
3523
+ configPath: FilePathSchema.describe("Path to flow configuration file"),
3524
+ event: z6.string().min(1).describe("Event as JSON string, file path, or URL"),
3525
+ flow: z6.string().optional().describe("Flow name for multi-flow configs"),
3526
+ platform: PlatformSchema.optional().describe("Override platform detection")
3527
+ };
3528
+ var PushInputSchema = z6.object(PushInputShape);
3529
+
2594
3530
  // src/commands/run/validators.ts
2595
3531
  function validateMode(mode) {
2596
3532
  const result = RunModeSchema.safeParse(mode);
@@ -2604,7 +3540,7 @@ function validateMode(mode) {
2604
3540
  }
2605
3541
  function validateFlowFile(filePath) {
2606
3542
  const absolutePath = resolveAsset(filePath, "bundle");
2607
- if (!existsSync2(absolutePath)) {
3543
+ if (!existsSync3(absolutePath)) {
2608
3544
  throw new Error(
2609
3545
  `Flow file not found: ${filePath}
2610
3546
  Resolved path: ${absolutePath}
@@ -2625,17 +3561,17 @@ function validatePort(port) {
2625
3561
  }
2626
3562
 
2627
3563
  // src/commands/run/utils.ts
2628
- import path12 from "path";
2629
- import fs12 from "fs-extra";
3564
+ import path13 from "path";
3565
+ import fs13 from "fs-extra";
2630
3566
  async function prepareBundleForRun(configPath, options) {
2631
- const configDir = path12.dirname(path12.resolve(configPath));
2632
- const tempDir = path12.join(
3567
+ const configDir = path13.dirname(path13.resolve(configPath));
3568
+ const tempDir = path13.join(
2633
3569
  configDir,
2634
3570
  ".tmp",
2635
3571
  `run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
2636
3572
  );
2637
- await fs12.ensureDir(tempDir);
2638
- const tempPath = path12.join(tempDir, "bundle.mjs");
3573
+ await fs13.ensureDir(tempDir);
3574
+ const tempPath = path13.join(tempDir, "bundle.mjs");
2639
3575
  await bundle(configPath, {
2640
3576
  cache: true,
2641
3577
  verbose: options.verbose,
@@ -2826,8 +3762,8 @@ async function runCommand(mode, options) {
2826
3762
  let flowPath = null;
2827
3763
  if (mode === "collect") {
2828
3764
  if (isPreBuilt) {
2829
- flowPath = path13.resolve(configPath);
2830
- logger2.debug(`Using pre-built flow: ${path13.basename(flowPath)}`);
3765
+ flowPath = path14.resolve(configPath);
3766
+ logger2.debug(`Using pre-built flow: ${path14.basename(flowPath)}`);
2831
3767
  } else {
2832
3768
  logger2.debug("Building flow bundle");
2833
3769
  flowPath = await prepareBundleForRun(configPath, {
@@ -2877,7 +3813,7 @@ async function run(mode, options) {
2877
3813
  const isPreBuilt = isPreBuiltConfig(flowFile);
2878
3814
  let flowPath;
2879
3815
  if (isPreBuilt) {
2880
- flowPath = path13.resolve(flowFile);
3816
+ flowPath = path14.resolve(flowFile);
2881
3817
  } else {
2882
3818
  flowPath = await prepareBundleForRun(flowFile, {
2883
3819
  verbose: options.verbose,
@@ -2906,7 +3842,7 @@ async function run(mode, options) {
2906
3842
  }
2907
3843
 
2908
3844
  // src/commands/validate/index.ts
2909
- import chalk2 from "chalk";
3845
+ import chalk3 from "chalk";
2910
3846
 
2911
3847
  // src/commands/validate/validators/event.ts
2912
3848
  import { schemas as schemas3 } from "@walkeros/core/dev";
@@ -2951,10 +3887,10 @@ function validateEvent(input) {
2951
3887
  const zodResult = PartialEventSchema.safeParse(input);
2952
3888
  if (!zodResult.success) {
2953
3889
  for (const issue of zodResult.error.issues) {
2954
- const path14 = issue.path.join(".");
2955
- if (path14 === "name") continue;
3890
+ const path16 = issue.path.join(".");
3891
+ if (path16 === "name") continue;
2956
3892
  errors.push({
2957
- path: path14 || "root",
3893
+ path: path16 || "root",
2958
3894
  message: issue.message,
2959
3895
  code: "SCHEMA_VALIDATION"
2960
3896
  });
@@ -2990,9 +3926,9 @@ function validateFlow(input, options = {}) {
2990
3926
  const zodResult = SetupSchema.safeParse(input);
2991
3927
  if (!zodResult.success) {
2992
3928
  for (const issue of zodResult.error.issues) {
2993
- const path14 = issue.path.join(".");
3929
+ const path16 = issue.path.join(".");
2994
3930
  errors.push({
2995
- path: path14 || "root",
3931
+ path: path16 || "root",
2996
3932
  message: issue.message,
2997
3933
  code: "SCHEMA_VALIDATION"
2998
3934
  });
@@ -3127,16 +4063,16 @@ function formatResult(result, options) {
3127
4063
  }
3128
4064
  lines.push("Validation Results:");
3129
4065
  for (const error of result.errors) {
3130
- lines.push(chalk2.red(` \u2717 ${error.path}: ${error.message}`));
4066
+ lines.push(chalk3.red(` \u2717 ${error.path}: ${error.message}`));
3131
4067
  }
3132
4068
  for (const warning of result.warnings) {
3133
- lines.push(chalk2.yellow(` \u26A0 ${warning.path}: ${warning.message}`));
4069
+ lines.push(chalk3.yellow(` \u26A0 ${warning.path}: ${warning.message}`));
3134
4070
  if (warning.suggestion) {
3135
- lines.push(chalk2.gray(` \u2192 ${warning.suggestion}`));
4071
+ lines.push(chalk3.gray(` \u2192 ${warning.suggestion}`));
3136
4072
  }
3137
4073
  }
3138
4074
  if (result.valid) {
3139
- lines.push(chalk2.green(` \u2713 All checks passed`));
4075
+ lines.push(chalk3.green(` \u2713 All checks passed`));
3140
4076
  }
3141
4077
  lines.push("");
3142
4078
  lines.push(
@@ -3145,24 +4081,30 @@ function formatResult(result, options) {
3145
4081
  return lines.join("\n");
3146
4082
  }
3147
4083
  async function validateCommand(options) {
3148
- const logger2 = createCommandLogger(options);
4084
+ const logger2 = createCommandLogger({ ...options, stderr: true });
3149
4085
  try {
3150
- const input = await loadJsonFromSource(options.input, {
3151
- name: options.type,
3152
- required: true
3153
- });
4086
+ let input;
4087
+ if (isStdinPiped() && !options.input) {
4088
+ const stdinContent = await readStdin();
4089
+ try {
4090
+ input = JSON.parse(stdinContent);
4091
+ } catch {
4092
+ throw new Error("Invalid JSON received on stdin");
4093
+ }
4094
+ } else {
4095
+ input = await loadJsonFromSource(options.input, {
4096
+ name: options.type,
4097
+ required: true
4098
+ });
4099
+ }
3154
4100
  const result = await validate(options.type, input, {
3155
4101
  flow: options.flow
3156
4102
  });
3157
- const output = formatResult(result, {
4103
+ const formatted = formatResult(result, {
3158
4104
  json: options.json,
3159
4105
  verbose: options.verbose
3160
4106
  });
3161
- if (options.json) {
3162
- console.log(output);
3163
- } else {
3164
- logger2.log(output);
3165
- }
4107
+ await writeResult(formatted + "\n", { output: options.output });
3166
4108
  if (!result.valid) {
3167
4109
  process.exit(1);
3168
4110
  }
@@ -3173,13 +4115,20 @@ async function validateCommand(options) {
3173
4115
  } catch (error) {
3174
4116
  const errorMessage = getErrorMessage(error);
3175
4117
  if (options.json) {
3176
- logger2.json({
3177
- valid: false,
3178
- type: options.type,
3179
- errors: [{ path: "input", message: errorMessage, code: "INPUT_ERROR" }],
3180
- warnings: [],
3181
- details: {}
3182
- });
4118
+ const errorOutput = JSON.stringify(
4119
+ {
4120
+ valid: false,
4121
+ type: options.type,
4122
+ errors: [
4123
+ { path: "input", message: errorMessage, code: "INPUT_ERROR" }
4124
+ ],
4125
+ warnings: [],
4126
+ details: {}
4127
+ },
4128
+ null,
4129
+ 2
4130
+ );
4131
+ await writeResult(errorOutput + "\n", { output: options.output });
3183
4132
  } else {
3184
4133
  logger2.error(`Error: ${errorMessage}`);
3185
4134
  }
@@ -3188,21 +4137,22 @@ async function validateCommand(options) {
3188
4137
  }
3189
4138
 
3190
4139
  // src/commands/cache.ts
3191
- import fs13 from "fs-extra";
4140
+ import fs14 from "fs-extra";
3192
4141
  function registerCacheCommand(program2) {
3193
4142
  const cache = program2.command("cache").description("Manage the CLI cache");
3194
4143
  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) => {
3195
4144
  const logger2 = createLogger({ silent: options.silent });
3196
4145
  const tmpDir = options.tmpDir;
3197
4146
  if (options.packages) {
3198
- await fs13.remove(getTmpPath(tmpDir, "cache", "packages"));
4147
+ await fs14.remove(getTmpPath(tmpDir, "cache", "packages"));
3199
4148
  logger2.log("Package cache cleared");
3200
4149
  } else if (options.builds) {
3201
- await fs13.remove(getTmpPath(tmpDir, "cache", "builds"));
4150
+ await fs14.remove(getTmpPath(tmpDir, "cache", "builds"));
3202
4151
  logger2.log("Build cache cleared");
3203
4152
  } else {
3204
- await fs13.remove(getTmpPath(tmpDir, "cache"));
3205
- logger2.log("All caches cleared");
4153
+ const cacheDir = getTmpPath(tmpDir, "cache");
4154
+ await fs14.remove(cacheDir);
4155
+ logger2.log(`Cache cleared: ${cacheDir}`);
3206
4156
  }
3207
4157
  });
3208
4158
  cache.command("info").description("Show cache statistics").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
@@ -3217,35 +4167,383 @@ function registerCacheCommand(program2) {
3217
4167
  logger2.log(`Cached builds: ${buildCount}`);
3218
4168
  });
3219
4169
  }
3220
- function registerCleanCommand(program2) {
3221
- program2.command("clean").description("Clear the entire temp directory (.tmp/)").option("--tmp-dir <dir>", "Custom temp directory").option("--silent", "Suppress output").action(async (options) => {
3222
- const logger2 = createLogger({ silent: options.silent });
3223
- const tmpDir = options.tmpDir || getDefaultTmpRoot();
3224
- await fs13.remove(tmpDir);
3225
- logger2.log(`Temp directory cleared: ${tmpDir}`);
3226
- });
3227
- }
3228
4170
  async function countEntries(dir) {
3229
- if (!await fs13.pathExists(dir)) return 0;
3230
- const entries = await fs13.readdir(dir);
4171
+ if (!await fs14.pathExists(dir)) return 0;
4172
+ const entries = await fs14.readdir(dir);
3231
4173
  return entries.length;
3232
4174
  }
3233
4175
 
4176
+ // src/commands/login/index.ts
4177
+ import { createServer } from "http";
4178
+ import { randomBytes } from "crypto";
4179
+ var LOGIN_TIMEOUT_MS = 2 * 60 * 1e3;
4180
+ function escapeHtml(str) {
4181
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
4182
+ }
4183
+ async function loginCommand(options) {
4184
+ const logger2 = createLogger({
4185
+ verbose: options.verbose,
4186
+ silent: options.silent,
4187
+ json: options.json
4188
+ });
4189
+ try {
4190
+ const result = await login({ url: options.url });
4191
+ if (options.json) {
4192
+ console.log(JSON.stringify(result, null, 2));
4193
+ } else if (result.success) {
4194
+ logger2.success(`Logged in as ${result.email}`);
4195
+ logger2.log(`Token stored in ${result.configPath}`);
4196
+ }
4197
+ process.exit(result.success ? 0 : 1);
4198
+ } catch (error) {
4199
+ const message = error instanceof Error ? error.message : String(error);
4200
+ if (options.json) {
4201
+ console.log(JSON.stringify({ success: false, error: message }, null, 2));
4202
+ } else {
4203
+ logger2.error(message);
4204
+ }
4205
+ process.exit(1);
4206
+ }
4207
+ }
4208
+ async function login(options = {}) {
4209
+ const appUrl = options.url || resolveAppUrl();
4210
+ const state = randomBytes(32).toString("hex");
4211
+ const { default: open2 } = await Promise.resolve().then(() => (init_open(), open_exports));
4212
+ return new Promise((resolve3, reject) => {
4213
+ const server = createServer(async (req, res) => {
4214
+ const url = new URL(req.url || "", `http://localhost`);
4215
+ if (url.pathname !== "/callback") {
4216
+ res.writeHead(404);
4217
+ res.end("Not found");
4218
+ return;
4219
+ }
4220
+ const code = url.searchParams.get("code");
4221
+ const returnedState = url.searchParams.get("state");
4222
+ if (returnedState !== state) {
4223
+ res.writeHead(200, { "Content-Type": "text/html" });
4224
+ res.end(
4225
+ "<html><body><h1>Authorization failed</h1><p>State mismatch. Please try again.</p></body></html>"
4226
+ );
4227
+ cleanup();
4228
+ reject(new Error("Authorization failed: state mismatch"));
4229
+ return;
4230
+ }
4231
+ if (!code) {
4232
+ res.writeHead(200, { "Content-Type": "text/html" });
4233
+ res.end(
4234
+ "<html><body><h1>Authorization failed</h1><p>No authorization code received.</p></body></html>"
4235
+ );
4236
+ cleanup();
4237
+ reject(new Error("Authorization failed: no code received"));
4238
+ return;
4239
+ }
4240
+ try {
4241
+ const exchangeResponse = await fetch(
4242
+ `${appUrl}/api/auth/cli/exchange`,
4243
+ {
4244
+ method: "POST",
4245
+ headers: { "Content-Type": "application/json" },
4246
+ body: JSON.stringify({ code })
4247
+ }
4248
+ );
4249
+ if (!exchangeResponse.ok) {
4250
+ const error = await exchangeResponse.json();
4251
+ res.writeHead(200, { "Content-Type": "text/html" });
4252
+ const safeMessage = escapeHtml(
4253
+ error.error?.message || "Unknown error"
4254
+ );
4255
+ res.end(
4256
+ `<html><body><h1>Authorization failed</h1><p>${safeMessage}</p></body></html>`
4257
+ );
4258
+ cleanup();
4259
+ reject(new Error(error.error?.message || "Token exchange failed"));
4260
+ return;
4261
+ }
4262
+ const data = await exchangeResponse.json();
4263
+ writeConfig({
4264
+ token: data.token,
4265
+ email: data.email,
4266
+ appUrl
4267
+ });
4268
+ const configPath = getConfigPath();
4269
+ res.writeHead(200, { "Content-Type": "text/html" });
4270
+ res.end(
4271
+ "<html><body><h1>Authorized!</h1><p>You can close this tab and return to the terminal.</p></body></html>"
4272
+ );
4273
+ cleanup();
4274
+ resolve3({ success: true, email: data.email, configPath });
4275
+ } catch {
4276
+ res.writeHead(200, { "Content-Type": "text/html" });
4277
+ res.end(
4278
+ "<html><body><h1>Authorization failed</h1><p>Could not exchange authorization code.</p></body></html>"
4279
+ );
4280
+ cleanup();
4281
+ reject(new Error("Token exchange failed"));
4282
+ }
4283
+ });
4284
+ const timeout = setTimeout(() => {
4285
+ cleanup();
4286
+ reject(new Error("Authorization timed out. Please try again."));
4287
+ }, LOGIN_TIMEOUT_MS);
4288
+ function cleanup() {
4289
+ clearTimeout(timeout);
4290
+ server.close();
4291
+ }
4292
+ server.listen(0, () => {
4293
+ const address = server.address();
4294
+ if (!address || typeof address === "string") {
4295
+ cleanup();
4296
+ reject(new Error("Failed to start callback server"));
4297
+ return;
4298
+ }
4299
+ const port = address.port;
4300
+ const authUrl = `${appUrl}/auth/cli?port=${port}&state=${state}`;
4301
+ open2(authUrl).catch(() => {
4302
+ console.error(
4303
+ `Could not open browser. Visit this URL manually:
4304
+
4305
+ ${authUrl}
4306
+ `
4307
+ );
4308
+ });
4309
+ });
4310
+ });
4311
+ }
4312
+
4313
+ // src/commands/logout/index.ts
4314
+ async function logoutCommand(options) {
4315
+ const logger2 = createLogger({
4316
+ verbose: options.verbose,
4317
+ silent: options.silent,
4318
+ json: options.json
4319
+ });
4320
+ const deleted = deleteConfig();
4321
+ const configPath = getConfigPath();
4322
+ if (options.json) {
4323
+ console.log(JSON.stringify({ success: true, deleted }));
4324
+ } else if (deleted) {
4325
+ logger2.success(`Logged out. Token removed from ${configPath}`);
4326
+ } else {
4327
+ logger2.log("No stored credentials found.");
4328
+ }
4329
+ process.exit(0);
4330
+ }
4331
+
4332
+ // src/commands/auth/index.ts
4333
+ async function whoami() {
4334
+ return apiRequest("/api/auth/whoami");
4335
+ }
4336
+ async function whoamiCommand(options) {
4337
+ const logger2 = createCommandLogger(options);
4338
+ try {
4339
+ const result = await whoami();
4340
+ if (options.json) {
4341
+ await writeResult(JSON.stringify(result, null, 2), options);
4342
+ } else {
4343
+ const data = result;
4344
+ if (data.email) logger2.log(`${data.email}`);
4345
+ if (data.userId) logger2.log(`User: ${data.userId}`);
4346
+ if (data.projectId) logger2.log(`Project: ${data.projectId}`);
4347
+ }
4348
+ } catch (error) {
4349
+ logger2.error(error instanceof Error ? error.message : String(error));
4350
+ process.exit(1);
4351
+ }
4352
+ }
4353
+
4354
+ // src/commands/projects/index.ts
4355
+ async function listProjects() {
4356
+ return apiRequest("/api/projects");
4357
+ }
4358
+ async function getProject(options = {}) {
4359
+ const id = options.projectId ?? requireProjectId();
4360
+ return apiRequest(`/api/projects/${id}`);
4361
+ }
4362
+ async function createProject(options) {
4363
+ return apiRequest("/api/projects", {
4364
+ method: "POST",
4365
+ body: JSON.stringify({ name: options.name })
4366
+ });
4367
+ }
4368
+ async function updateProject(options) {
4369
+ const id = options.projectId ?? requireProjectId();
4370
+ return apiRequest(`/api/projects/${id}`, {
4371
+ method: "PATCH",
4372
+ body: JSON.stringify({ name: options.name })
4373
+ });
4374
+ }
4375
+ async function deleteProject(options = {}) {
4376
+ const id = options.projectId ?? requireProjectId();
4377
+ return apiRequest(`/api/projects/${id}`, { method: "DELETE" });
4378
+ }
4379
+ async function handleResult(fn, options) {
4380
+ const logger2 = createCommandLogger(options);
4381
+ try {
4382
+ const result = await fn();
4383
+ await writeResult(JSON.stringify(result, null, 2), options);
4384
+ } catch (error) {
4385
+ logger2.error(error instanceof Error ? error.message : String(error));
4386
+ process.exit(1);
4387
+ }
4388
+ }
4389
+ async function listProjectsCommand(options) {
4390
+ await handleResult(() => listProjects(), options);
4391
+ }
4392
+ async function getProjectCommand(projectId, options) {
4393
+ await handleResult(
4394
+ () => getProject({ projectId: projectId ?? options.project }),
4395
+ options
4396
+ );
4397
+ }
4398
+ async function createProjectCommand(name, options) {
4399
+ await handleResult(() => createProject({ name }), options);
4400
+ }
4401
+ async function updateProjectCommand(projectId, options) {
4402
+ const name = options.name;
4403
+ if (!name) {
4404
+ throw new Error("Missing required option: --name <name>");
4405
+ }
4406
+ await handleResult(
4407
+ () => updateProject({
4408
+ projectId: projectId ?? options.project,
4409
+ name
4410
+ }),
4411
+ options
4412
+ );
4413
+ }
4414
+ async function deleteProjectCommand(projectId, options) {
4415
+ await handleResult(
4416
+ () => deleteProject({ projectId: projectId ?? options.project }),
4417
+ options
4418
+ );
4419
+ }
4420
+
4421
+ // src/commands/flows/index.ts
4422
+ async function listFlows(options = {}) {
4423
+ const id = options.projectId ?? requireProjectId();
4424
+ const params = new URLSearchParams();
4425
+ if (options.sort) params.set("sort", options.sort);
4426
+ if (options.order) params.set("order", options.order);
4427
+ if (options.includeDeleted) params.set("include_deleted", "true");
4428
+ const qs = params.toString();
4429
+ return apiRequest(`/api/projects/${id}/flows${qs ? `?${qs}` : ""}`);
4430
+ }
4431
+ async function getFlow(options) {
4432
+ const id = options.projectId ?? requireProjectId();
4433
+ return apiRequest(`/api/projects/${id}/flows/${options.flowId}`);
4434
+ }
4435
+ async function createFlow(options) {
4436
+ const id = options.projectId ?? requireProjectId();
4437
+ return apiRequest(`/api/projects/${id}/flows`, {
4438
+ method: "POST",
4439
+ body: JSON.stringify({ name: options.name, content: options.content })
4440
+ });
4441
+ }
4442
+ async function updateFlow(options) {
4443
+ const id = options.projectId ?? requireProjectId();
4444
+ const body = {};
4445
+ if (options.name !== void 0) body.name = options.name;
4446
+ if (options.content !== void 0) body.content = options.content;
4447
+ return apiRequest(`/api/projects/${id}/flows/${options.flowId}`, {
4448
+ method: "PATCH",
4449
+ body: JSON.stringify(body)
4450
+ });
4451
+ }
4452
+ async function deleteFlow(options) {
4453
+ const id = options.projectId ?? requireProjectId();
4454
+ return apiRequest(`/api/projects/${id}/flows/${options.flowId}`, {
4455
+ method: "DELETE"
4456
+ });
4457
+ }
4458
+ async function duplicateFlow(options) {
4459
+ const id = options.projectId ?? requireProjectId();
4460
+ const body = options.name ? { name: options.name } : {};
4461
+ return apiRequest(`/api/projects/${id}/flows/${options.flowId}/duplicate`, {
4462
+ method: "POST",
4463
+ body: JSON.stringify(body)
4464
+ });
4465
+ }
4466
+ async function handleResult2(fn, options) {
4467
+ const logger2 = createCommandLogger(options);
4468
+ try {
4469
+ const result = await fn();
4470
+ await writeResult(JSON.stringify(result, null, 2), options);
4471
+ } catch (error) {
4472
+ logger2.error(error instanceof Error ? error.message : String(error));
4473
+ process.exit(1);
4474
+ }
4475
+ }
4476
+ async function listFlowsCommand(options) {
4477
+ await handleResult2(
4478
+ () => listFlows({
4479
+ projectId: options.project,
4480
+ sort: options.sort,
4481
+ order: options.order,
4482
+ includeDeleted: options.includeDeleted
4483
+ }),
4484
+ options
4485
+ );
4486
+ }
4487
+ async function getFlowCommand(flowId, options) {
4488
+ await handleResult2(
4489
+ () => getFlow({ flowId, projectId: options.project }),
4490
+ options
4491
+ );
4492
+ }
4493
+ async function createFlowCommand(name, options) {
4494
+ const content = options.content ? JSON.parse(options.content) : JSON.parse(await readFlowStdin());
4495
+ await handleResult2(
4496
+ () => createFlow({ name, content, projectId: options.project }),
4497
+ options
4498
+ );
4499
+ }
4500
+ async function updateFlowCommand(flowId, options) {
4501
+ const content = options.content ? JSON.parse(options.content) : void 0;
4502
+ await handleResult2(
4503
+ () => updateFlow({
4504
+ flowId,
4505
+ name: options.name,
4506
+ content,
4507
+ projectId: options.project
4508
+ }),
4509
+ options
4510
+ );
4511
+ }
4512
+ async function deleteFlowCommand(flowId, options) {
4513
+ await handleResult2(
4514
+ () => deleteFlow({ flowId, projectId: options.project }),
4515
+ options
4516
+ );
4517
+ }
4518
+ async function duplicateFlowCommand(flowId, options) {
4519
+ await handleResult2(
4520
+ () => duplicateFlow({ flowId, name: options.name, projectId: options.project }),
4521
+ options
4522
+ );
4523
+ }
4524
+ async function readFlowStdin() {
4525
+ if (!isStdinPiped()) {
4526
+ throw new Error("Content required: use --content or pipe via stdin");
4527
+ }
4528
+ return readStdin();
4529
+ }
4530
+
3234
4531
  // src/index.ts
3235
4532
  var program = new Command();
3236
4533
  program.name("walkeros").description("walkerOS CLI - Bundle and deploy walkerOS components").version(VERSION);
3237
4534
  program.hook("preAction", (thisCommand, actionCommand) => {
3238
4535
  const options = actionCommand.opts();
3239
- if (!options.silent && !options.json) {
3240
- console.log(`${chalk3.hex("#01b5e2")("walkerOS")} v${VERSION}`);
4536
+ if (!options.silent && !options.json && process.stdout.isTTY) {
4537
+ printBanner(VERSION);
3241
4538
  }
3242
4539
  });
3243
- program.command("bundle [file]").description("Bundle NPM packages with custom code").option("--flow <name>", "flow name for multi-flow configs").option("--all", "build all flows for multi-flow configs").option("--stats", "show bundle statistics").option("--json", "output as JSON (implies --stats)").option("--no-cache", "disable package caching").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option(
4540
+ program.command("bundle [file]").description("Bundle NPM packages with custom code").option("-o, --output <path>", "write bundle to file or directory").option("--flow <name>", "flow name for multi-flow configs").option("--all", "build all flows for multi-flow configs").option("--stats", "show bundle statistics").option("--json", "output as JSON (implies --stats)").option("--no-cache", "disable package caching").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option(
3244
4541
  "--dockerfile [file]",
3245
4542
  "generate Dockerfile (or copy custom file) to dist/"
3246
4543
  ).action(async (file, options) => {
3247
4544
  await bundleCommand({
3248
- config: file || "bundle.config.json",
4545
+ config: file,
4546
+ output: options.output,
3249
4547
  flow: options.flow,
3250
4548
  all: options.all,
3251
4549
  stats: options.stats,
@@ -3256,12 +4554,13 @@ program.command("bundle [file]").description("Bundle NPM packages with custom co
3256
4554
  dockerfile: options.dockerfile
3257
4555
  });
3258
4556
  });
3259
- program.command("simulate [file]").description("Simulate event processing and capture API calls").option(
4557
+ program.command("simulate [file]").description("Simulate event processing and capture API calls").option("-o, --output <path>", "write result to file").option(
3260
4558
  "-e, --event <source>",
3261
4559
  "event to simulate (JSON string, file path, or URL)"
3262
4560
  ).option("--flow <name>", "flow name for multi-flow configs").option("-p, --platform <platform>", "platform override (web or server)").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (file, options) => {
3263
4561
  await simulateCommand({
3264
- config: file || "bundle.config.json",
4562
+ config: file,
4563
+ output: options.output,
3265
4564
  event: options.event,
3266
4565
  flow: options.flow,
3267
4566
  platform: options.platform,
@@ -3273,9 +4572,10 @@ program.command("simulate [file]").description("Simulate event processing and ca
3273
4572
  program.command("push [file]").description("Push an event through the flow with real API execution").requiredOption(
3274
4573
  "-e, --event <source>",
3275
4574
  "event to push (JSON string, file path, or URL)"
3276
- ).option("--flow <name>", "flow name for multi-flow configs").option("-p, --platform <platform>", "platform override (web or server)").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (file, options) => {
4575
+ ).option("-o, --output <path>", "write result to file").option("--flow <name>", "flow name for multi-flow configs").option("-p, --platform <platform>", "platform override (web or server)").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (file, options) => {
3277
4576
  await pushCommand({
3278
- config: file || "bundle.config.json",
4577
+ config: file,
4578
+ output: options.output,
3279
4579
  event: options.event,
3280
4580
  flow: options.flow,
3281
4581
  platform: options.platform,
@@ -3284,10 +4584,11 @@ program.command("push [file]").description("Push an event through the flow with
3284
4584
  silent: options.silent
3285
4585
  });
3286
4586
  });
3287
- program.command("validate <type> [input]").description("Validate event, flow, or mapping configuration").option("--flow <name>", "flow name for multi-flow configs").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option("--strict", "fail on warnings").action(async (type, input, options) => {
4587
+ program.command("validate <type> [input]").description("Validate event, flow, or mapping configuration").option("-o, --output <path>", "write result to file").option("--flow <name>", "flow name for multi-flow configs").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").option("--strict", "fail on warnings").action(async (type, input, options) => {
3288
4588
  await validateCommand({
3289
4589
  type,
3290
4590
  input,
4591
+ output: options.output,
3291
4592
  flow: options.flow,
3292
4593
  json: options.json,
3293
4594
  verbose: options.verbose,
@@ -3295,6 +4596,65 @@ program.command("validate <type> [input]").description("Validate event, flow, or
3295
4596
  strict: options.strict
3296
4597
  });
3297
4598
  });
4599
+ var authCmd = program.command("auth").description("Authentication and identity");
4600
+ authCmd.command("login").description("Log in to walkerOS via browser").option("--url <url>", "custom app URL").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
4601
+ await loginCommand({
4602
+ url: options.url,
4603
+ json: options.json,
4604
+ verbose: options.verbose,
4605
+ silent: options.silent
4606
+ });
4607
+ });
4608
+ authCmd.command("logout").description("Remove stored credentials").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
4609
+ await logoutCommand({
4610
+ json: options.json,
4611
+ verbose: options.verbose,
4612
+ silent: options.silent
4613
+ });
4614
+ });
4615
+ authCmd.command("whoami").description("Show current user identity").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
4616
+ await whoamiCommand({
4617
+ output: options.output,
4618
+ json: options.json,
4619
+ verbose: options.verbose,
4620
+ silent: options.silent
4621
+ });
4622
+ });
4623
+ var projectsCmd = program.command("projects").description("Manage walkerOS projects");
4624
+ projectsCmd.command("list").description("List all projects").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
4625
+ await listProjectsCommand(options);
4626
+ });
4627
+ projectsCmd.command("get [projectId]").description("Get project details").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (projectId, options) => {
4628
+ await getProjectCommand(projectId, options);
4629
+ });
4630
+ projectsCmd.command("create <name>").description("Create a new project").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (name, options) => {
4631
+ await createProjectCommand(name, options);
4632
+ });
4633
+ projectsCmd.command("update [projectId]").description("Update a project").requiredOption("--name <name>", "new project name").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (projectId, options) => {
4634
+ await updateProjectCommand(projectId, options);
4635
+ });
4636
+ projectsCmd.command("delete [projectId]").description("Delete a project").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (projectId, options) => {
4637
+ await deleteProjectCommand(projectId, options);
4638
+ });
4639
+ var flowsCmd = program.command("flows").description("Manage walkerOS flows");
4640
+ flowsCmd.command("list").description("List all flows in a project").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("--sort <field>", "sort by: name, updated_at, created_at").option("--order <dir>", "sort order: asc, desc").option("--include-deleted", "include soft-deleted flows").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (options) => {
4641
+ await listFlowsCommand(options);
4642
+ });
4643
+ flowsCmd.command("get <flowId>").description("Get a flow with its full content").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
4644
+ await getFlowCommand(flowId, options);
4645
+ });
4646
+ flowsCmd.command("create <name>").description("Create a new flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("-c, --content <json>", "Flow.Setup JSON string or file path").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (name, options) => {
4647
+ await createFlowCommand(name, options);
4648
+ });
4649
+ flowsCmd.command("update <flowId>").description("Update a flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("--name <name>", "new flow name").option("-c, --content <json>", "new Flow.Setup JSON string or file path").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
4650
+ await updateFlowCommand(flowId, options);
4651
+ });
4652
+ flowsCmd.command("delete <flowId>").description("Delete a flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
4653
+ await deleteFlowCommand(flowId, options);
4654
+ });
4655
+ flowsCmd.command("duplicate <flowId>").description("Duplicate a flow").option("--project <id>", "project ID (defaults to WALKEROS_PROJECT_ID)").option("--name <name>", "name for the copy").option("-o, --output <path>", "output file path").option("--json", "output as JSON").option("-v, --verbose", "verbose output").option("-s, --silent", "suppress output").action(async (flowId, options) => {
4656
+ await duplicateFlowCommand(flowId, options);
4657
+ });
3298
4658
  var runCmd = program.command("run").description("Run walkerOS flows in collect or serve mode");
3299
4659
  runCmd.command("collect [file]").description(
3300
4660
  "Run collector mode (event collection endpoint). Defaults to server-collect.mjs if no file specified."
@@ -3323,16 +4683,34 @@ runCmd.command("serve [file]").description(
3323
4683
  });
3324
4684
  });
3325
4685
  registerCacheCommand(program);
3326
- registerCleanCommand(program);
3327
4686
  program.parse();
3328
4687
  export {
4688
+ apiRequest,
4689
+ authenticatedFetch,
3329
4690
  bundle,
3330
4691
  bundleCommand,
4692
+ createFlow,
4693
+ createProject,
4694
+ deleteFlow,
4695
+ deleteProject,
4696
+ duplicateFlow,
4697
+ getAuthHeaders,
4698
+ getFlow,
4699
+ getProject,
4700
+ getToken,
4701
+ listFlows,
4702
+ listProjects,
4703
+ push,
3331
4704
  pushCommand,
4705
+ requireProjectId,
4706
+ resolveBaseUrl,
3332
4707
  run,
3333
4708
  runCommand,
3334
4709
  simulate,
3335
4710
  simulateCommand,
3336
- validate
4711
+ updateFlow,
4712
+ updateProject,
4713
+ validate,
4714
+ whoami
3337
4715
  };
3338
4716
  //# sourceMappingURL=index.js.map