@automagik/omni 2.260404.1 → 2.260405.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/db/drizzle/0014_overrated_silver_fox.sql +5 -0
  2. package/db/drizzle/0015_burly_trauma.sql +27 -0
  3. package/db/drizzle/meta/0014_snapshot.json +6784 -0
  4. package/db/drizzle/meta/0015_snapshot.json +7025 -0
  5. package/db/drizzle/meta/_journal.json +14 -0
  6. package/dist/commands/close.d.ts +11 -0
  7. package/dist/commands/close.d.ts.map +1 -0
  8. package/dist/commands/done.d.ts +14 -0
  9. package/dist/commands/done.d.ts.map +1 -0
  10. package/dist/commands/film.d.ts +16 -0
  11. package/dist/commands/film.d.ts.map +1 -0
  12. package/dist/commands/imagine.d.ts +16 -0
  13. package/dist/commands/imagine.d.ts.map +1 -0
  14. package/dist/commands/listen.d.ts +18 -0
  15. package/dist/commands/listen.d.ts.map +1 -0
  16. package/dist/commands/open.d.ts +12 -0
  17. package/dist/commands/open.d.ts.map +1 -0
  18. package/dist/commands/persons.d.ts +4 -0
  19. package/dist/commands/persons.d.ts.map +1 -1
  20. package/dist/commands/react.d.ts +11 -0
  21. package/dist/commands/react.d.ts.map +1 -0
  22. package/dist/commands/say.d.ts +12 -0
  23. package/dist/commands/say.d.ts.map +1 -0
  24. package/dist/commands/see.d.ts +15 -0
  25. package/dist/commands/see.d.ts.map +1 -0
  26. package/dist/commands/send.d.ts.map +1 -1
  27. package/dist/commands/speak.d.ts +18 -0
  28. package/dist/commands/speak.d.ts.map +1 -0
  29. package/dist/commands/use.d.ts +12 -0
  30. package/dist/commands/use.d.ts.map +1 -0
  31. package/dist/commands/where.d.ts +11 -0
  32. package/dist/commands/where.d.ts.map +1 -0
  33. package/dist/context.d.ts +43 -0
  34. package/dist/context.d.ts.map +1 -0
  35. package/dist/index.js +2130 -753
  36. package/dist/server/index.js +30156 -2930
  37. package/package.json +9 -9
package/dist/index.js CHANGED
@@ -65,6 +65,500 @@ var __export = (target, all) => {
65
65
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
66
66
  var __require = import.meta.require;
67
67
 
68
+ // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
69
+ function assembleStyles() {
70
+ const codes = new Map;
71
+ for (const [groupName, group] of Object.entries(styles)) {
72
+ for (const [styleName, style] of Object.entries(group)) {
73
+ styles[styleName] = {
74
+ open: `\x1B[${style[0]}m`,
75
+ close: `\x1B[${style[1]}m`
76
+ };
77
+ group[styleName] = styles[styleName];
78
+ codes.set(style[0], style[1]);
79
+ }
80
+ Object.defineProperty(styles, groupName, {
81
+ value: group,
82
+ enumerable: false
83
+ });
84
+ }
85
+ Object.defineProperty(styles, "codes", {
86
+ value: codes,
87
+ enumerable: false
88
+ });
89
+ styles.color.close = "\x1B[39m";
90
+ styles.bgColor.close = "\x1B[49m";
91
+ styles.color.ansi = wrapAnsi16();
92
+ styles.color.ansi256 = wrapAnsi256();
93
+ styles.color.ansi16m = wrapAnsi16m();
94
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
95
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
96
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
97
+ Object.defineProperties(styles, {
98
+ rgbToAnsi256: {
99
+ value(red, green, blue) {
100
+ if (red === green && green === blue) {
101
+ if (red < 8) {
102
+ return 16;
103
+ }
104
+ if (red > 248) {
105
+ return 231;
106
+ }
107
+ return Math.round((red - 8) / 247 * 24) + 232;
108
+ }
109
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
110
+ },
111
+ enumerable: false
112
+ },
113
+ hexToRgb: {
114
+ value(hex) {
115
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
116
+ if (!matches) {
117
+ return [0, 0, 0];
118
+ }
119
+ let [colorString] = matches;
120
+ if (colorString.length === 3) {
121
+ colorString = [...colorString].map((character) => character + character).join("");
122
+ }
123
+ const integer = Number.parseInt(colorString, 16);
124
+ return [
125
+ integer >> 16 & 255,
126
+ integer >> 8 & 255,
127
+ integer & 255
128
+ ];
129
+ },
130
+ enumerable: false
131
+ },
132
+ hexToAnsi256: {
133
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
134
+ enumerable: false
135
+ },
136
+ ansi256ToAnsi: {
137
+ value(code) {
138
+ if (code < 8) {
139
+ return 30 + code;
140
+ }
141
+ if (code < 16) {
142
+ return 90 + (code - 8);
143
+ }
144
+ let red;
145
+ let green;
146
+ let blue;
147
+ if (code >= 232) {
148
+ red = ((code - 232) * 10 + 8) / 255;
149
+ green = red;
150
+ blue = red;
151
+ } else {
152
+ code -= 16;
153
+ const remainder = code % 36;
154
+ red = Math.floor(code / 36) / 5;
155
+ green = Math.floor(remainder / 6) / 5;
156
+ blue = remainder % 6 / 5;
157
+ }
158
+ const value = Math.max(red, green, blue) * 2;
159
+ if (value === 0) {
160
+ return 30;
161
+ }
162
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
163
+ if (value === 2) {
164
+ result += 60;
165
+ }
166
+ return result;
167
+ },
168
+ enumerable: false
169
+ },
170
+ rgbToAnsi: {
171
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
172
+ enumerable: false
173
+ },
174
+ hexToAnsi: {
175
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
176
+ enumerable: false
177
+ }
178
+ });
179
+ return styles;
180
+ }
181
+ var ANSI_BACKGROUND_OFFSET = 10, wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`, wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`, wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`, styles, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default;
182
+ var init_ansi_styles = __esm(() => {
183
+ styles = {
184
+ modifier: {
185
+ reset: [0, 0],
186
+ bold: [1, 22],
187
+ dim: [2, 22],
188
+ italic: [3, 23],
189
+ underline: [4, 24],
190
+ overline: [53, 55],
191
+ inverse: [7, 27],
192
+ hidden: [8, 28],
193
+ strikethrough: [9, 29]
194
+ },
195
+ color: {
196
+ black: [30, 39],
197
+ red: [31, 39],
198
+ green: [32, 39],
199
+ yellow: [33, 39],
200
+ blue: [34, 39],
201
+ magenta: [35, 39],
202
+ cyan: [36, 39],
203
+ white: [37, 39],
204
+ blackBright: [90, 39],
205
+ gray: [90, 39],
206
+ grey: [90, 39],
207
+ redBright: [91, 39],
208
+ greenBright: [92, 39],
209
+ yellowBright: [93, 39],
210
+ blueBright: [94, 39],
211
+ magentaBright: [95, 39],
212
+ cyanBright: [96, 39],
213
+ whiteBright: [97, 39]
214
+ },
215
+ bgColor: {
216
+ bgBlack: [40, 49],
217
+ bgRed: [41, 49],
218
+ bgGreen: [42, 49],
219
+ bgYellow: [43, 49],
220
+ bgBlue: [44, 49],
221
+ bgMagenta: [45, 49],
222
+ bgCyan: [46, 49],
223
+ bgWhite: [47, 49],
224
+ bgBlackBright: [100, 49],
225
+ bgGray: [100, 49],
226
+ bgGrey: [100, 49],
227
+ bgRedBright: [101, 49],
228
+ bgGreenBright: [102, 49],
229
+ bgYellowBright: [103, 49],
230
+ bgBlueBright: [104, 49],
231
+ bgMagentaBright: [105, 49],
232
+ bgCyanBright: [106, 49],
233
+ bgWhiteBright: [107, 49]
234
+ }
235
+ };
236
+ modifierNames = Object.keys(styles.modifier);
237
+ foregroundColorNames = Object.keys(styles.color);
238
+ backgroundColorNames = Object.keys(styles.bgColor);
239
+ colorNames = [...foregroundColorNames, ...backgroundColorNames];
240
+ ansiStyles = assembleStyles();
241
+ ansi_styles_default = ansiStyles;
242
+ });
243
+
244
+ // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
245
+ import process2 from "process";
246
+ import os from "os";
247
+ import tty from "tty";
248
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
249
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
250
+ const position = argv.indexOf(prefix + flag);
251
+ const terminatorPosition = argv.indexOf("--");
252
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
253
+ }
254
+ function envForceColor() {
255
+ if ("FORCE_COLOR" in env) {
256
+ if (env.FORCE_COLOR === "true") {
257
+ return 1;
258
+ }
259
+ if (env.FORCE_COLOR === "false") {
260
+ return 0;
261
+ }
262
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
263
+ }
264
+ }
265
+ function translateLevel(level) {
266
+ if (level === 0) {
267
+ return false;
268
+ }
269
+ return {
270
+ level,
271
+ hasBasic: true,
272
+ has256: level >= 2,
273
+ has16m: level >= 3
274
+ };
275
+ }
276
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
277
+ const noFlagForceColor = envForceColor();
278
+ if (noFlagForceColor !== undefined) {
279
+ flagForceColor = noFlagForceColor;
280
+ }
281
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
282
+ if (forceColor === 0) {
283
+ return 0;
284
+ }
285
+ if (sniffFlags) {
286
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
287
+ return 3;
288
+ }
289
+ if (hasFlag("color=256")) {
290
+ return 2;
291
+ }
292
+ }
293
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) {
294
+ return 1;
295
+ }
296
+ if (haveStream && !streamIsTTY && forceColor === undefined) {
297
+ return 0;
298
+ }
299
+ const min = forceColor || 0;
300
+ if (env.TERM === "dumb") {
301
+ return min;
302
+ }
303
+ if (process2.platform === "win32") {
304
+ const osRelease = os.release().split(".");
305
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
306
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
307
+ }
308
+ return 1;
309
+ }
310
+ if ("CI" in env) {
311
+ if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => (key in env))) {
312
+ return 3;
313
+ }
314
+ if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => (sign in env)) || env.CI_NAME === "codeship") {
315
+ return 1;
316
+ }
317
+ return min;
318
+ }
319
+ if ("TEAMCITY_VERSION" in env) {
320
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
321
+ }
322
+ if (env.COLORTERM === "truecolor") {
323
+ return 3;
324
+ }
325
+ if (env.TERM === "xterm-kitty") {
326
+ return 3;
327
+ }
328
+ if (env.TERM === "xterm-ghostty") {
329
+ return 3;
330
+ }
331
+ if (env.TERM === "wezterm") {
332
+ return 3;
333
+ }
334
+ if ("TERM_PROGRAM" in env) {
335
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
336
+ switch (env.TERM_PROGRAM) {
337
+ case "iTerm.app": {
338
+ return version >= 3 ? 3 : 2;
339
+ }
340
+ case "Apple_Terminal": {
341
+ return 2;
342
+ }
343
+ }
344
+ }
345
+ if (/-256(color)?$/i.test(env.TERM)) {
346
+ return 2;
347
+ }
348
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
349
+ return 1;
350
+ }
351
+ if ("COLORTERM" in env) {
352
+ return 1;
353
+ }
354
+ return min;
355
+ }
356
+ function createSupportsColor(stream, options = {}) {
357
+ const level = _supportsColor(stream, {
358
+ streamIsTTY: stream && stream.isTTY,
359
+ ...options
360
+ });
361
+ return translateLevel(level);
362
+ }
363
+ var env, flagForceColor, supportsColor, supports_color_default;
364
+ var init_supports_color = __esm(() => {
365
+ ({ env } = process2);
366
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
367
+ flagForceColor = 0;
368
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
369
+ flagForceColor = 1;
370
+ }
371
+ supportsColor = {
372
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
373
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
374
+ };
375
+ supports_color_default = supportsColor;
376
+ });
377
+
378
+ // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/utilities.js
379
+ function stringReplaceAll(string, substring, replacer) {
380
+ let index = string.indexOf(substring);
381
+ if (index === -1) {
382
+ return string;
383
+ }
384
+ const substringLength = substring.length;
385
+ let endIndex = 0;
386
+ let returnValue = "";
387
+ do {
388
+ returnValue += string.slice(endIndex, index) + substring + replacer;
389
+ endIndex = index + substringLength;
390
+ index = string.indexOf(substring, endIndex);
391
+ } while (index !== -1);
392
+ returnValue += string.slice(endIndex);
393
+ return returnValue;
394
+ }
395
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
396
+ let endIndex = 0;
397
+ let returnValue = "";
398
+ do {
399
+ const gotCR = string[index - 1] === "\r";
400
+ returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? `\r
401
+ ` : `
402
+ `) + postfix;
403
+ endIndex = index + 1;
404
+ index = string.indexOf(`
405
+ `, endIndex);
406
+ } while (index !== -1);
407
+ returnValue += string.slice(endIndex);
408
+ return returnValue;
409
+ }
410
+
411
+ // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/index.js
412
+ class Chalk {
413
+ constructor(options) {
414
+ return chalkFactory(options);
415
+ }
416
+ }
417
+ function createChalk(options) {
418
+ return chalkFactory(options);
419
+ }
420
+ var stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles2, applyOptions = (object, options = {}) => {
421
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
422
+ throw new Error("The `level` option should be an integer from 0 to 3");
423
+ }
424
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
425
+ object.level = options.level === undefined ? colorLevel : options.level;
426
+ }, chalkFactory = (options) => {
427
+ const chalk = (...strings) => strings.join(" ");
428
+ applyOptions(chalk, options);
429
+ Object.setPrototypeOf(chalk, createChalk.prototype);
430
+ return chalk;
431
+ }, getModelAnsi = (model, level, type, ...arguments_) => {
432
+ if (model === "rgb") {
433
+ if (level === "ansi16m") {
434
+ return ansi_styles_default[type].ansi16m(...arguments_);
435
+ }
436
+ if (level === "ansi256") {
437
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
438
+ }
439
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
440
+ }
441
+ if (model === "hex") {
442
+ return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
443
+ }
444
+ return ansi_styles_default[type][model](...arguments_);
445
+ }, usedModels, proto, createStyler = (open, close, parent) => {
446
+ let openAll;
447
+ let closeAll;
448
+ if (parent === undefined) {
449
+ openAll = open;
450
+ closeAll = close;
451
+ } else {
452
+ openAll = parent.openAll + open;
453
+ closeAll = close + parent.closeAll;
454
+ }
455
+ return {
456
+ open,
457
+ close,
458
+ openAll,
459
+ closeAll,
460
+ parent
461
+ };
462
+ }, createBuilder = (self2, _styler, _isEmpty) => {
463
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
464
+ Object.setPrototypeOf(builder, proto);
465
+ builder[GENERATOR] = self2;
466
+ builder[STYLER] = _styler;
467
+ builder[IS_EMPTY] = _isEmpty;
468
+ return builder;
469
+ }, applyStyle = (self2, string) => {
470
+ if (self2.level <= 0 || !string) {
471
+ return self2[IS_EMPTY] ? "" : string;
472
+ }
473
+ let styler = self2[STYLER];
474
+ if (styler === undefined) {
475
+ return string;
476
+ }
477
+ const { openAll, closeAll } = styler;
478
+ if (string.includes("\x1B")) {
479
+ while (styler !== undefined) {
480
+ string = stringReplaceAll(string, styler.close, styler.open);
481
+ styler = styler.parent;
482
+ }
483
+ }
484
+ const lfIndex = string.indexOf(`
485
+ `);
486
+ if (lfIndex !== -1) {
487
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
488
+ }
489
+ return openAll + string + closeAll;
490
+ }, chalk, chalkStderr, source_default;
491
+ var init_source = __esm(() => {
492
+ init_ansi_styles();
493
+ init_supports_color();
494
+ ({ stdout: stdoutColor, stderr: stderrColor } = supports_color_default);
495
+ GENERATOR = Symbol("GENERATOR");
496
+ STYLER = Symbol("STYLER");
497
+ IS_EMPTY = Symbol("IS_EMPTY");
498
+ levelMapping = [
499
+ "ansi",
500
+ "ansi",
501
+ "ansi256",
502
+ "ansi16m"
503
+ ];
504
+ styles2 = Object.create(null);
505
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
506
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
507
+ styles2[styleName] = {
508
+ get() {
509
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
510
+ Object.defineProperty(this, styleName, { value: builder });
511
+ return builder;
512
+ }
513
+ };
514
+ }
515
+ styles2.visible = {
516
+ get() {
517
+ const builder = createBuilder(this, this[STYLER], true);
518
+ Object.defineProperty(this, "visible", { value: builder });
519
+ return builder;
520
+ }
521
+ };
522
+ usedModels = ["rgb", "hex", "ansi256"];
523
+ for (const model of usedModels) {
524
+ styles2[model] = {
525
+ get() {
526
+ const { level } = this;
527
+ return function(...arguments_) {
528
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
529
+ return createBuilder(this, styler, this[IS_EMPTY]);
530
+ };
531
+ }
532
+ };
533
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
534
+ styles2[bgModel] = {
535
+ get() {
536
+ const { level } = this;
537
+ return function(...arguments_) {
538
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
539
+ return createBuilder(this, styler, this[IS_EMPTY]);
540
+ };
541
+ }
542
+ };
543
+ }
544
+ proto = Object.defineProperties(() => {}, {
545
+ ...styles2,
546
+ level: {
547
+ enumerable: true,
548
+ get() {
549
+ return this[GENERATOR].level;
550
+ },
551
+ set(level) {
552
+ this[GENERATOR].level = level;
553
+ }
554
+ }
555
+ });
556
+ Object.defineProperties(createChalk.prototype, styles2);
557
+ chalk = createChalk();
558
+ chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
559
+ source_default = chalk;
560
+ });
561
+
68
562
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/lib/error.js
69
563
  var require_error = __commonJS((exports) => {
70
564
  class CommanderError extends Error {
@@ -2300,6 +2794,211 @@ var init_config = __esm(() => {
2300
2794
  };
2301
2795
  });
2302
2796
 
2797
+ // src/output.ts
2798
+ var exports_output = {};
2799
+ __export(exports_output, {
2800
+ warn: () => warn,
2801
+ success: () => success,
2802
+ setMaxCellWidth: () => setMaxCellWidth,
2803
+ raw: () => raw,
2804
+ list: () => list,
2805
+ keyValue: () => keyValue,
2806
+ info: () => info,
2807
+ header: () => header,
2808
+ getCurrentFormat: () => getCurrentFormat,
2809
+ flushStdout: () => flushStdout,
2810
+ error: () => error,
2811
+ disableColors: () => disableColors,
2812
+ dim: () => dim,
2813
+ data: () => data,
2814
+ areColorsEnabled: () => areColorsEnabled
2815
+ });
2816
+ function disableColors() {
2817
+ colorsEnabled = false;
2818
+ }
2819
+ function areColorsEnabled() {
2820
+ return colorsEnabled && process.stdout.isTTY !== false;
2821
+ }
2822
+ function c() {
2823
+ if (areColorsEnabled()) {
2824
+ return source_default;
2825
+ }
2826
+ return source_default;
2827
+ }
2828
+ function getCurrentFormat() {
2829
+ return getOutputFormat();
2830
+ }
2831
+ function success(message, data) {
2832
+ const format = getCurrentFormat();
2833
+ if (format === "json") {
2834
+ console.log(JSON.stringify({ success: true, message, data }, null, 2));
2835
+ } else {
2836
+ console.log(c().green("\u2713"), message);
2837
+ if (data !== undefined) {
2838
+ console.log(c().dim(JSON.stringify(data, null, 2)));
2839
+ }
2840
+ }
2841
+ }
2842
+ function error(message, details, exitCode = 1) {
2843
+ const format = getCurrentFormat();
2844
+ if (format === "json") {
2845
+ console.error(JSON.stringify({ success: false, error: message, details }, null, 2));
2846
+ } else {
2847
+ console.error(c().red("\u2717"), message);
2848
+ if (details !== undefined) {
2849
+ console.error(c().dim(JSON.stringify(details, null, 2)));
2850
+ }
2851
+ }
2852
+ process.exit(exitCode);
2853
+ }
2854
+ function warn(message) {
2855
+ const format = getCurrentFormat();
2856
+ if (format === "json") {
2857
+ console.error(JSON.stringify({ warning: message }));
2858
+ } else {
2859
+ console.log(c().yellow("\u26A0"), message);
2860
+ }
2861
+ }
2862
+ function info(message) {
2863
+ const format = getCurrentFormat();
2864
+ if (format === "json") {
2865
+ console.error(JSON.stringify({ info: message }));
2866
+ } else {
2867
+ console.log(c().blue("\u2139"), message);
2868
+ }
2869
+ }
2870
+ function data(value) {
2871
+ const format = getCurrentFormat();
2872
+ if (format === "json") {
2873
+ console.log(JSON.stringify(value, null, 2));
2874
+ } else {
2875
+ if (Array.isArray(value)) {
2876
+ printTable(value);
2877
+ } else if (typeof value === "object" && value !== null) {
2878
+ printObject(value);
2879
+ } else {
2880
+ console.log(value);
2881
+ }
2882
+ }
2883
+ }
2884
+ function setMaxCellWidth(width) {
2885
+ maxCellWidth = width;
2886
+ }
2887
+ function list(items, options) {
2888
+ const format = getCurrentFormat();
2889
+ if (format === "json") {
2890
+ console.log(JSON.stringify(options?.rawData ?? items, null, 2));
2891
+ return;
2892
+ }
2893
+ if (items.length === 0) {
2894
+ console.log(c().dim(options?.emptyMessage ?? "No items found."));
2895
+ return;
2896
+ }
2897
+ printTable(items);
2898
+ }
2899
+ function printTable(items) {
2900
+ if (items.length === 0)
2901
+ return;
2902
+ const first = items[0];
2903
+ if (typeof first !== "object" || first === null) {
2904
+ for (const item of items) {
2905
+ console.log(item);
2906
+ }
2907
+ return;
2908
+ }
2909
+ const keys = Object.keys(first);
2910
+ if (keys.length === 0)
2911
+ return;
2912
+ const widths = {};
2913
+ for (const key of keys) {
2914
+ widths[key] = key.length;
2915
+ }
2916
+ for (const item of items) {
2917
+ const obj = item;
2918
+ for (const key of keys) {
2919
+ const val = formatCellValue(obj[key]);
2920
+ widths[key] = Math.max(widths[key], val.length);
2921
+ }
2922
+ }
2923
+ const header = keys.map((k) => k.toUpperCase().padEnd(widths[k])).join(" ");
2924
+ console.log(c().bold(header));
2925
+ const separator = keys.map((k) => "-".repeat(widths[k])).join(" ");
2926
+ console.log(c().dim(separator));
2927
+ for (const item of items) {
2928
+ const obj = item;
2929
+ const row = keys.map((k) => formatCellValue(obj[k]).padEnd(widths[k])).join(" ");
2930
+ console.log(row);
2931
+ }
2932
+ }
2933
+ function formatCellValue(value) {
2934
+ if (value === null || value === undefined) {
2935
+ return "-";
2936
+ }
2937
+ if (typeof value === "boolean") {
2938
+ return value ? "yes" : "no";
2939
+ }
2940
+ if (typeof value === "object") {
2941
+ return JSON.stringify(value);
2942
+ }
2943
+ const str = String(value);
2944
+ if (maxCellWidth > 0 && str.length > maxCellWidth) {
2945
+ return `${str.slice(0, maxCellWidth - 3)}...`;
2946
+ }
2947
+ return str;
2948
+ }
2949
+ function printObject(obj) {
2950
+ const maxKeyLen = Math.max(...Object.keys(obj).map((k) => k.length));
2951
+ for (const [key, value] of Object.entries(obj)) {
2952
+ const label = key.padEnd(maxKeyLen);
2953
+ const formattedValue = formatValue(value);
2954
+ console.log(`${c().cyan(label)} ${formattedValue}`);
2955
+ }
2956
+ }
2957
+ function formatValue(value) {
2958
+ if (value === null || value === undefined) {
2959
+ return c().dim("-");
2960
+ }
2961
+ if (typeof value === "boolean") {
2962
+ return value ? c().green("yes") : c().red("no");
2963
+ }
2964
+ if (typeof value === "object") {
2965
+ return c().dim(JSON.stringify(value));
2966
+ }
2967
+ return String(value);
2968
+ }
2969
+ function keyValue(key, value) {
2970
+ const format = getCurrentFormat();
2971
+ if (format === "json") {
2972
+ console.log(JSON.stringify({ [key]: value }, null, 2));
2973
+ } else {
2974
+ console.log(`${c().cyan(key)}: ${formatValue(value)}`);
2975
+ }
2976
+ }
2977
+ function header(title) {
2978
+ if (getCurrentFormat() === "human") {
2979
+ console.log(`
2980
+ ${c().bold.underline(title)}`);
2981
+ }
2982
+ }
2983
+ function dim(text) {
2984
+ if (getCurrentFormat() === "human") {
2985
+ console.log(c().dim(text));
2986
+ }
2987
+ }
2988
+ function raw(text) {
2989
+ console.log(text);
2990
+ }
2991
+ function flushStdout() {
2992
+ return new Promise((resolve) => {
2993
+ process.stdout.write("", () => resolve());
2994
+ });
2995
+ }
2996
+ var colorsEnabled = true, maxCellWidth = 50;
2997
+ var init_output = __esm(() => {
2998
+ init_source();
2999
+ init_config();
3000
+ });
3001
+
2303
3002
  // ../../node_modules/.bun/cli-spinners@2.9.2/node_modules/cli-spinners/spinners.json
2304
3003
  var require_spinners = __commonJS((exports, module) => {
2305
3004
  module.exports = {
@@ -20481,7 +21180,7 @@ var require_node_transport = __commonJS((exports) => {
20481
21180
  var util_1 = require_util();
20482
21181
  var tls_1 = __require("tls");
20483
21182
  var { resolve: resolve2 } = __require("path");
20484
- var { readFile, existsSync: existsSync5 } = __require("fs");
21183
+ var { readFile: readFile2, existsSync: existsSync6 } = __require("fs");
20485
21184
  var dns = __require("dns");
20486
21185
  var VERSION2 = "2.29.3";
20487
21186
  var LANG = "nats.js";
@@ -20597,10 +21296,10 @@ var require_node_transport = __commonJS((exports) => {
20597
21296
  const d = (0, nats_base_client_1.deferred)();
20598
21297
  try {
20599
21298
  fn = resolve2(fn);
20600
- if (!existsSync5(fn)) {
21299
+ if (!existsSync6(fn)) {
20601
21300
  d.reject(new Error(`${fn} doesn't exist`));
20602
21301
  }
20603
- readFile(fn, (err, data2) => {
21302
+ readFile2(fn, (err, data2) => {
20604
21303
  if (err) {
20605
21304
  return d.reject(err);
20606
21305
  }
@@ -29505,7 +30204,7 @@ function createSupportsColor2(stream, options3 = {}) {
29505
30204
  return translateLevel2(level);
29506
30205
  }
29507
30206
  var env2, flagForceColor2, supportsColor2, supports_color_default2;
29508
- var init_supports_color = __esm(() => {
30207
+ var init_supports_color2 = __esm(() => {
29509
30208
  ({ env: env2 } = process10);
29510
30209
  if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false") || hasFlag2("color=never")) {
29511
30210
  flagForceColor2 = 0;
@@ -29532,7 +30231,7 @@ var require_node3 = __commonJS((exports, module) => {
29532
30231
  exports.destroy = util3.deprecate(() => {}, "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
29533
30232
  exports.colors = [6, 2, 3, 4, 5, 1];
29534
30233
  try {
29535
- const supportsColor3 = (init_supports_color(), __toCommonJS(exports_supports_color));
30234
+ const supportsColor3 = (init_supports_color2(), __toCommonJS(exports_supports_color));
29536
30235
  if (supportsColor3 && (supportsColor3.stderr || supportsColor3).level >= 2) {
29537
30236
  exports.colors = [
29538
30237
  20,
@@ -40460,10 +41159,10 @@ var require_path = __commonJS((exports) => {
40460
41159
  function isAbsolute(path) {
40461
41160
  return path.charAt(0) === "/";
40462
41161
  }
40463
- function join8(...args) {
41162
+ function join9(...args) {
40464
41163
  return normalizePath(args.join("/"));
40465
41164
  }
40466
- function dirname5(path) {
41165
+ function dirname6(path) {
40467
41166
  const result = splitPath(path);
40468
41167
  const root = result[0] || "";
40469
41168
  let dir = result[1];
@@ -40475,17 +41174,17 @@ var require_path = __commonJS((exports) => {
40475
41174
  }
40476
41175
  return root + dir;
40477
41176
  }
40478
- function basename3(path, ext) {
41177
+ function basename6(path, ext) {
40479
41178
  let f2 = splitPath(path)[2] || "";
40480
41179
  if (ext && f2.slice(ext.length * -1) === ext) {
40481
41180
  f2 = f2.slice(0, f2.length - ext.length);
40482
41181
  }
40483
41182
  return f2;
40484
41183
  }
40485
- exports.basename = basename3;
40486
- exports.dirname = dirname5;
41184
+ exports.basename = basename6;
41185
+ exports.dirname = dirname6;
40487
41186
  exports.isAbsolute = isAbsolute;
40488
- exports.join = join8;
41187
+ exports.join = join9;
40489
41188
  exports.normalizePath = normalizePath;
40490
41189
  exports.relative = relative;
40491
41190
  exports.resolve = resolve3;
@@ -74127,500 +74826,8 @@ var require_cjs5 = __commonJS((exports) => {
74127
74826
  exports.makeFetchTransport = index.makeFetchTransport;
74128
74827
  });
74129
74828
 
74130
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
74131
- var ANSI_BACKGROUND_OFFSET = 10;
74132
- var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
74133
- var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
74134
- var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
74135
- var styles = {
74136
- modifier: {
74137
- reset: [0, 0],
74138
- bold: [1, 22],
74139
- dim: [2, 22],
74140
- italic: [3, 23],
74141
- underline: [4, 24],
74142
- overline: [53, 55],
74143
- inverse: [7, 27],
74144
- hidden: [8, 28],
74145
- strikethrough: [9, 29]
74146
- },
74147
- color: {
74148
- black: [30, 39],
74149
- red: [31, 39],
74150
- green: [32, 39],
74151
- yellow: [33, 39],
74152
- blue: [34, 39],
74153
- magenta: [35, 39],
74154
- cyan: [36, 39],
74155
- white: [37, 39],
74156
- blackBright: [90, 39],
74157
- gray: [90, 39],
74158
- grey: [90, 39],
74159
- redBright: [91, 39],
74160
- greenBright: [92, 39],
74161
- yellowBright: [93, 39],
74162
- blueBright: [94, 39],
74163
- magentaBright: [95, 39],
74164
- cyanBright: [96, 39],
74165
- whiteBright: [97, 39]
74166
- },
74167
- bgColor: {
74168
- bgBlack: [40, 49],
74169
- bgRed: [41, 49],
74170
- bgGreen: [42, 49],
74171
- bgYellow: [43, 49],
74172
- bgBlue: [44, 49],
74173
- bgMagenta: [45, 49],
74174
- bgCyan: [46, 49],
74175
- bgWhite: [47, 49],
74176
- bgBlackBright: [100, 49],
74177
- bgGray: [100, 49],
74178
- bgGrey: [100, 49],
74179
- bgRedBright: [101, 49],
74180
- bgGreenBright: [102, 49],
74181
- bgYellowBright: [103, 49],
74182
- bgBlueBright: [104, 49],
74183
- bgMagentaBright: [105, 49],
74184
- bgCyanBright: [106, 49],
74185
- bgWhiteBright: [107, 49]
74186
- }
74187
- };
74188
- var modifierNames = Object.keys(styles.modifier);
74189
- var foregroundColorNames = Object.keys(styles.color);
74190
- var backgroundColorNames = Object.keys(styles.bgColor);
74191
- var colorNames = [...foregroundColorNames, ...backgroundColorNames];
74192
- function assembleStyles() {
74193
- const codes = new Map;
74194
- for (const [groupName, group] of Object.entries(styles)) {
74195
- for (const [styleName, style] of Object.entries(group)) {
74196
- styles[styleName] = {
74197
- open: `\x1B[${style[0]}m`,
74198
- close: `\x1B[${style[1]}m`
74199
- };
74200
- group[styleName] = styles[styleName];
74201
- codes.set(style[0], style[1]);
74202
- }
74203
- Object.defineProperty(styles, groupName, {
74204
- value: group,
74205
- enumerable: false
74206
- });
74207
- }
74208
- Object.defineProperty(styles, "codes", {
74209
- value: codes,
74210
- enumerable: false
74211
- });
74212
- styles.color.close = "\x1B[39m";
74213
- styles.bgColor.close = "\x1B[49m";
74214
- styles.color.ansi = wrapAnsi16();
74215
- styles.color.ansi256 = wrapAnsi256();
74216
- styles.color.ansi16m = wrapAnsi16m();
74217
- styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
74218
- styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
74219
- styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
74220
- Object.defineProperties(styles, {
74221
- rgbToAnsi256: {
74222
- value(red, green, blue) {
74223
- if (red === green && green === blue) {
74224
- if (red < 8) {
74225
- return 16;
74226
- }
74227
- if (red > 248) {
74228
- return 231;
74229
- }
74230
- return Math.round((red - 8) / 247 * 24) + 232;
74231
- }
74232
- return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
74233
- },
74234
- enumerable: false
74235
- },
74236
- hexToRgb: {
74237
- value(hex) {
74238
- const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
74239
- if (!matches) {
74240
- return [0, 0, 0];
74241
- }
74242
- let [colorString] = matches;
74243
- if (colorString.length === 3) {
74244
- colorString = [...colorString].map((character) => character + character).join("");
74245
- }
74246
- const integer = Number.parseInt(colorString, 16);
74247
- return [
74248
- integer >> 16 & 255,
74249
- integer >> 8 & 255,
74250
- integer & 255
74251
- ];
74252
- },
74253
- enumerable: false
74254
- },
74255
- hexToAnsi256: {
74256
- value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
74257
- enumerable: false
74258
- },
74259
- ansi256ToAnsi: {
74260
- value(code) {
74261
- if (code < 8) {
74262
- return 30 + code;
74263
- }
74264
- if (code < 16) {
74265
- return 90 + (code - 8);
74266
- }
74267
- let red;
74268
- let green;
74269
- let blue;
74270
- if (code >= 232) {
74271
- red = ((code - 232) * 10 + 8) / 255;
74272
- green = red;
74273
- blue = red;
74274
- } else {
74275
- code -= 16;
74276
- const remainder = code % 36;
74277
- red = Math.floor(code / 36) / 5;
74278
- green = Math.floor(remainder / 6) / 5;
74279
- blue = remainder % 6 / 5;
74280
- }
74281
- const value = Math.max(red, green, blue) * 2;
74282
- if (value === 0) {
74283
- return 30;
74284
- }
74285
- let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
74286
- if (value === 2) {
74287
- result += 60;
74288
- }
74289
- return result;
74290
- },
74291
- enumerable: false
74292
- },
74293
- rgbToAnsi: {
74294
- value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
74295
- enumerable: false
74296
- },
74297
- hexToAnsi: {
74298
- value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
74299
- enumerable: false
74300
- }
74301
- });
74302
- return styles;
74303
- }
74304
- var ansiStyles = assembleStyles();
74305
- var ansi_styles_default = ansiStyles;
74306
-
74307
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
74308
- import process2 from "process";
74309
- import os from "os";
74310
- import tty from "tty";
74311
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
74312
- const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
74313
- const position = argv.indexOf(prefix + flag);
74314
- const terminatorPosition = argv.indexOf("--");
74315
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
74316
- }
74317
- var { env } = process2;
74318
- var flagForceColor;
74319
- if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
74320
- flagForceColor = 0;
74321
- } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
74322
- flagForceColor = 1;
74323
- }
74324
- function envForceColor() {
74325
- if ("FORCE_COLOR" in env) {
74326
- if (env.FORCE_COLOR === "true") {
74327
- return 1;
74328
- }
74329
- if (env.FORCE_COLOR === "false") {
74330
- return 0;
74331
- }
74332
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
74333
- }
74334
- }
74335
- function translateLevel(level) {
74336
- if (level === 0) {
74337
- return false;
74338
- }
74339
- return {
74340
- level,
74341
- hasBasic: true,
74342
- has256: level >= 2,
74343
- has16m: level >= 3
74344
- };
74345
- }
74346
- function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
74347
- const noFlagForceColor = envForceColor();
74348
- if (noFlagForceColor !== undefined) {
74349
- flagForceColor = noFlagForceColor;
74350
- }
74351
- const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
74352
- if (forceColor === 0) {
74353
- return 0;
74354
- }
74355
- if (sniffFlags) {
74356
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
74357
- return 3;
74358
- }
74359
- if (hasFlag("color=256")) {
74360
- return 2;
74361
- }
74362
- }
74363
- if ("TF_BUILD" in env && "AGENT_NAME" in env) {
74364
- return 1;
74365
- }
74366
- if (haveStream && !streamIsTTY && forceColor === undefined) {
74367
- return 0;
74368
- }
74369
- const min = forceColor || 0;
74370
- if (env.TERM === "dumb") {
74371
- return min;
74372
- }
74373
- if (process2.platform === "win32") {
74374
- const osRelease = os.release().split(".");
74375
- if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
74376
- return Number(osRelease[2]) >= 14931 ? 3 : 2;
74377
- }
74378
- return 1;
74379
- }
74380
- if ("CI" in env) {
74381
- if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => (key in env))) {
74382
- return 3;
74383
- }
74384
- if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => (sign in env)) || env.CI_NAME === "codeship") {
74385
- return 1;
74386
- }
74387
- return min;
74388
- }
74389
- if ("TEAMCITY_VERSION" in env) {
74390
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
74391
- }
74392
- if (env.COLORTERM === "truecolor") {
74393
- return 3;
74394
- }
74395
- if (env.TERM === "xterm-kitty") {
74396
- return 3;
74397
- }
74398
- if (env.TERM === "xterm-ghostty") {
74399
- return 3;
74400
- }
74401
- if (env.TERM === "wezterm") {
74402
- return 3;
74403
- }
74404
- if ("TERM_PROGRAM" in env) {
74405
- const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
74406
- switch (env.TERM_PROGRAM) {
74407
- case "iTerm.app": {
74408
- return version >= 3 ? 3 : 2;
74409
- }
74410
- case "Apple_Terminal": {
74411
- return 2;
74412
- }
74413
- }
74414
- }
74415
- if (/-256(color)?$/i.test(env.TERM)) {
74416
- return 2;
74417
- }
74418
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
74419
- return 1;
74420
- }
74421
- if ("COLORTERM" in env) {
74422
- return 1;
74423
- }
74424
- return min;
74425
- }
74426
- function createSupportsColor(stream, options = {}) {
74427
- const level = _supportsColor(stream, {
74428
- streamIsTTY: stream && stream.isTTY,
74429
- ...options
74430
- });
74431
- return translateLevel(level);
74432
- }
74433
- var supportsColor = {
74434
- stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
74435
- stderr: createSupportsColor({ isTTY: tty.isatty(2) })
74436
- };
74437
- var supports_color_default = supportsColor;
74438
-
74439
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/utilities.js
74440
- function stringReplaceAll(string, substring, replacer) {
74441
- let index = string.indexOf(substring);
74442
- if (index === -1) {
74443
- return string;
74444
- }
74445
- const substringLength = substring.length;
74446
- let endIndex = 0;
74447
- let returnValue = "";
74448
- do {
74449
- returnValue += string.slice(endIndex, index) + substring + replacer;
74450
- endIndex = index + substringLength;
74451
- index = string.indexOf(substring, endIndex);
74452
- } while (index !== -1);
74453
- returnValue += string.slice(endIndex);
74454
- return returnValue;
74455
- }
74456
- function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
74457
- let endIndex = 0;
74458
- let returnValue = "";
74459
- do {
74460
- const gotCR = string[index - 1] === "\r";
74461
- returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? `\r
74462
- ` : `
74463
- `) + postfix;
74464
- endIndex = index + 1;
74465
- index = string.indexOf(`
74466
- `, endIndex);
74467
- } while (index !== -1);
74468
- returnValue += string.slice(endIndex);
74469
- return returnValue;
74470
- }
74471
-
74472
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/index.js
74473
- var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
74474
- var GENERATOR = Symbol("GENERATOR");
74475
- var STYLER = Symbol("STYLER");
74476
- var IS_EMPTY = Symbol("IS_EMPTY");
74477
- var levelMapping = [
74478
- "ansi",
74479
- "ansi",
74480
- "ansi256",
74481
- "ansi16m"
74482
- ];
74483
- var styles2 = Object.create(null);
74484
- var applyOptions = (object, options = {}) => {
74485
- if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
74486
- throw new Error("The `level` option should be an integer from 0 to 3");
74487
- }
74488
- const colorLevel = stdoutColor ? stdoutColor.level : 0;
74489
- object.level = options.level === undefined ? colorLevel : options.level;
74490
- };
74491
-
74492
- class Chalk {
74493
- constructor(options) {
74494
- return chalkFactory(options);
74495
- }
74496
- }
74497
- var chalkFactory = (options) => {
74498
- const chalk = (...strings) => strings.join(" ");
74499
- applyOptions(chalk, options);
74500
- Object.setPrototypeOf(chalk, createChalk.prototype);
74501
- return chalk;
74502
- };
74503
- function createChalk(options) {
74504
- return chalkFactory(options);
74505
- }
74506
- Object.setPrototypeOf(createChalk.prototype, Function.prototype);
74507
- for (const [styleName, style] of Object.entries(ansi_styles_default)) {
74508
- styles2[styleName] = {
74509
- get() {
74510
- const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
74511
- Object.defineProperty(this, styleName, { value: builder });
74512
- return builder;
74513
- }
74514
- };
74515
- }
74516
- styles2.visible = {
74517
- get() {
74518
- const builder = createBuilder(this, this[STYLER], true);
74519
- Object.defineProperty(this, "visible", { value: builder });
74520
- return builder;
74521
- }
74522
- };
74523
- var getModelAnsi = (model, level, type, ...arguments_) => {
74524
- if (model === "rgb") {
74525
- if (level === "ansi16m") {
74526
- return ansi_styles_default[type].ansi16m(...arguments_);
74527
- }
74528
- if (level === "ansi256") {
74529
- return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
74530
- }
74531
- return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
74532
- }
74533
- if (model === "hex") {
74534
- return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
74535
- }
74536
- return ansi_styles_default[type][model](...arguments_);
74537
- };
74538
- var usedModels = ["rgb", "hex", "ansi256"];
74539
- for (const model of usedModels) {
74540
- styles2[model] = {
74541
- get() {
74542
- const { level } = this;
74543
- return function(...arguments_) {
74544
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
74545
- return createBuilder(this, styler, this[IS_EMPTY]);
74546
- };
74547
- }
74548
- };
74549
- const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
74550
- styles2[bgModel] = {
74551
- get() {
74552
- const { level } = this;
74553
- return function(...arguments_) {
74554
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
74555
- return createBuilder(this, styler, this[IS_EMPTY]);
74556
- };
74557
- }
74558
- };
74559
- }
74560
- var proto = Object.defineProperties(() => {}, {
74561
- ...styles2,
74562
- level: {
74563
- enumerable: true,
74564
- get() {
74565
- return this[GENERATOR].level;
74566
- },
74567
- set(level) {
74568
- this[GENERATOR].level = level;
74569
- }
74570
- }
74571
- });
74572
- var createStyler = (open, close, parent) => {
74573
- let openAll;
74574
- let closeAll;
74575
- if (parent === undefined) {
74576
- openAll = open;
74577
- closeAll = close;
74578
- } else {
74579
- openAll = parent.openAll + open;
74580
- closeAll = close + parent.closeAll;
74581
- }
74582
- return {
74583
- open,
74584
- close,
74585
- openAll,
74586
- closeAll,
74587
- parent
74588
- };
74589
- };
74590
- var createBuilder = (self2, _styler, _isEmpty) => {
74591
- const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
74592
- Object.setPrototypeOf(builder, proto);
74593
- builder[GENERATOR] = self2;
74594
- builder[STYLER] = _styler;
74595
- builder[IS_EMPTY] = _isEmpty;
74596
- return builder;
74597
- };
74598
- var applyStyle = (self2, string) => {
74599
- if (self2.level <= 0 || !string) {
74600
- return self2[IS_EMPTY] ? "" : string;
74601
- }
74602
- let styler = self2[STYLER];
74603
- if (styler === undefined) {
74604
- return string;
74605
- }
74606
- const { openAll, closeAll } = styler;
74607
- if (string.includes("\x1B")) {
74608
- while (styler !== undefined) {
74609
- string = stringReplaceAll(string, styler.close, styler.open);
74610
- styler = styler.parent;
74611
- }
74612
- }
74613
- const lfIndex = string.indexOf(`
74614
- `);
74615
- if (lfIndex !== -1) {
74616
- string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
74617
- }
74618
- return openAll + string + closeAll;
74619
- };
74620
- Object.defineProperties(createChalk.prototype, styles2);
74621
- var chalk = createChalk();
74622
- var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
74623
- var source_default = chalk;
74829
+ // src/index.ts
74830
+ init_source();
74624
74831
 
74625
74832
  // ../../node_modules/.bun/commander@13.1.0/node_modules/commander/esm.mjs
74626
74833
  var import__ = __toESM(require_commander(), 1);
@@ -75767,6 +75974,58 @@ function createOmniClient(config) {
75767
75974
  if (!json?.data)
75768
75975
  throw new OmniApiError("Person not found", "NOT_FOUND", undefined, 404);
75769
75976
  return json.data;
75977
+ },
75978
+ async update(id, data) {
75979
+ const resp = await apiFetch(`${baseUrl}/api/v2/persons/${id}`, {
75980
+ method: "PATCH",
75981
+ headers: { "Content-Type": "application/json" },
75982
+ body: JSON.stringify(data)
75983
+ });
75984
+ const json = await resp.json();
75985
+ if (!resp.ok)
75986
+ throw OmniApiError.from(json, resp.status);
75987
+ if (!json?.data)
75988
+ throw new OmniApiError("Person not found", "NOT_FOUND", undefined, 404);
75989
+ return json.data;
75990
+ },
75991
+ async link(identityA, identityB) {
75992
+ const resp = await apiFetch(`${baseUrl}/api/v2/persons/link`, {
75993
+ method: "POST",
75994
+ headers: { "Content-Type": "application/json" },
75995
+ body: JSON.stringify({ identityA, identityB })
75996
+ });
75997
+ const json = await resp.json();
75998
+ if (!resp.ok)
75999
+ throw OmniApiError.from(json, resp.status);
76000
+ if (!json?.data)
76001
+ throw new OmniApiError("Link failed", "INTERNAL_ERROR", undefined, 500);
76002
+ return json.data;
76003
+ },
76004
+ async unlink(identityId, reason) {
76005
+ const resp = await apiFetch(`${baseUrl}/api/v2/persons/unlink`, {
76006
+ method: "POST",
76007
+ headers: { "Content-Type": "application/json" },
76008
+ body: JSON.stringify({ identityId, reason })
76009
+ });
76010
+ const json = await resp.json();
76011
+ if (!resp.ok)
76012
+ throw OmniApiError.from(json, resp.status);
76013
+ if (!json?.data)
76014
+ throw new OmniApiError("Unlink failed", "INTERNAL_ERROR", undefined, 500);
76015
+ return json.data;
76016
+ },
76017
+ async merge(sourcePersonId, targetPersonId, reason) {
76018
+ const resp = await apiFetch(`${baseUrl}/api/v2/persons/merge`, {
76019
+ method: "POST",
76020
+ headers: { "Content-Type": "application/json" },
76021
+ body: JSON.stringify({ sourcePersonId, targetPersonId, reason })
76022
+ });
76023
+ const json = await resp.json();
76024
+ if (!resp.ok)
76025
+ throw OmniApiError.from(json, resp.status);
76026
+ if (!json?.data)
76027
+ throw new OmniApiError("Merge failed", "INTERNAL_ERROR", undefined, 500);
76028
+ return json.data;
75770
76029
  }
75771
76030
  },
75772
76031
  access: {
@@ -76405,6 +76664,160 @@ function createOmniClient(config) {
76405
76664
  throw OmniApiError.from(await resp.json(), resp.status);
76406
76665
  }
76407
76666
  },
76667
+ context: {
76668
+ async get() {
76669
+ const resp = await apiFetch(`${baseUrl}/api/v2/context`, {});
76670
+ const json = await resp.json();
76671
+ if (!resp.ok)
76672
+ throw OmniApiError.from(json, resp.status);
76673
+ return json?.data ?? { instanceId: null, chatId: null, messageId: null, activeInstanceId: null, updatedAt: null };
76674
+ },
76675
+ async set(body) {
76676
+ const resp = await apiFetch(`${baseUrl}/api/v2/context`, {
76677
+ method: "POST",
76678
+ headers: { "Content-Type": "application/json" },
76679
+ body: JSON.stringify(body)
76680
+ });
76681
+ if (!resp.ok)
76682
+ throw OmniApiError.from(await resp.json(), resp.status);
76683
+ },
76684
+ async use(instanceId) {
76685
+ const resp = await apiFetch(`${baseUrl}/api/v2/context/use`, {
76686
+ method: "POST",
76687
+ headers: { "Content-Type": "application/json" },
76688
+ body: JSON.stringify({ instanceId })
76689
+ });
76690
+ if (!resp.ok)
76691
+ throw OmniApiError.from(await resp.json(), resp.status);
76692
+ },
76693
+ async clear() {
76694
+ const resp = await apiFetch(`${baseUrl}/api/v2/context`, {
76695
+ method: "DELETE"
76696
+ });
76697
+ if (!resp.ok)
76698
+ throw OmniApiError.from(await resp.json(), resp.status);
76699
+ }
76700
+ },
76701
+ media: {
76702
+ async tts(body) {
76703
+ const resp = await apiFetch(`${baseUrl}/api/v2/media/tts`, {
76704
+ method: "POST",
76705
+ headers: { "Content-Type": "application/json" },
76706
+ body: JSON.stringify(body)
76707
+ });
76708
+ const json = await resp.json();
76709
+ if (!resp.ok)
76710
+ throw OmniApiError.from(json, resp.status);
76711
+ const data = json?.data;
76712
+ if (!data) {
76713
+ throw new OmniApiError("TTS response missing data", "INVALID_RESPONSE", undefined, 500);
76714
+ }
76715
+ return {
76716
+ provider: data.provider,
76717
+ mimeType: data.mimeType,
76718
+ durationMs: data.durationMs,
76719
+ sizeBytes: data.sizeBytes,
76720
+ audio: Buffer.from(data.audioBase64, "base64")
76721
+ };
76722
+ },
76723
+ async stt(body) {
76724
+ const resp = await apiFetch(`${baseUrl}/api/v2/media/stt`, {
76725
+ method: "POST",
76726
+ headers: { "Content-Type": "application/json" },
76727
+ body: JSON.stringify({
76728
+ audioBase64: body.audio.toString("base64"),
76729
+ mimeType: body.mimeType,
76730
+ provider: body.provider,
76731
+ language: body.language,
76732
+ timestamps: body.timestamps,
76733
+ model: body.model
76734
+ })
76735
+ });
76736
+ const json = await resp.json();
76737
+ if (!resp.ok)
76738
+ throw OmniApiError.from(json, resp.status);
76739
+ const data = json?.data;
76740
+ if (!data) {
76741
+ throw new OmniApiError("STT response missing data", "INVALID_RESPONSE", undefined, 500);
76742
+ }
76743
+ return {
76744
+ provider: data.provider,
76745
+ text: data.text,
76746
+ segments: data.segments,
76747
+ detectedLanguage: data.detectedLanguage,
76748
+ processingMs: data.processingMs
76749
+ };
76750
+ },
76751
+ async imagine(body) {
76752
+ const resp = await apiFetch(`${baseUrl}/api/v2/media/imagine`, {
76753
+ method: "POST",
76754
+ headers: { "Content-Type": "application/json" },
76755
+ body: JSON.stringify(body)
76756
+ });
76757
+ const json = await resp.json();
76758
+ if (!resp.ok)
76759
+ throw OmniApiError.from(json, resp.status);
76760
+ const data = json?.data;
76761
+ if (!data) {
76762
+ throw new OmniApiError("Imagine response missing data", "INVALID_RESPONSE", undefined, 500);
76763
+ }
76764
+ return data;
76765
+ },
76766
+ async vision(body) {
76767
+ const resp = await apiFetch(`${baseUrl}/api/v2/media/vision`, {
76768
+ method: "POST",
76769
+ headers: { "Content-Type": "application/json" },
76770
+ body: JSON.stringify({
76771
+ mediaBase64: body.media.toString("base64"),
76772
+ mimeType: body.mimeType,
76773
+ provider: body.provider,
76774
+ prompt: body.prompt,
76775
+ language: body.language,
76776
+ maxTokens: body.maxTokens
76777
+ })
76778
+ });
76779
+ const json = await resp.json();
76780
+ if (!resp.ok)
76781
+ throw OmniApiError.from(json, resp.status);
76782
+ const data = json?.data;
76783
+ if (!data) {
76784
+ throw new OmniApiError("Vision response missing data", "INVALID_RESPONSE", undefined, 500);
76785
+ }
76786
+ return {
76787
+ provider: data.provider,
76788
+ text: data.text,
76789
+ processingMs: data.processingMs
76790
+ };
76791
+ },
76792
+ async film(body) {
76793
+ const resp = await apiFetch(`${baseUrl}/api/v2/media/film`, {
76794
+ method: "POST",
76795
+ headers: { "Content-Type": "application/json" },
76796
+ body: JSON.stringify(body)
76797
+ });
76798
+ const json = await resp.json();
76799
+ if (!resp.ok)
76800
+ throw OmniApiError.from(json, resp.status);
76801
+ const data = json?.data;
76802
+ if (!data) {
76803
+ throw new OmniApiError("Film response missing data", "INVALID_RESPONSE", undefined, 500);
76804
+ }
76805
+ return data;
76806
+ }
76807
+ },
76808
+ turns: {
76809
+ async close(body) {
76810
+ const resp = await apiFetch(`${baseUrl}/api/v2/turns/close`, {
76811
+ method: "POST",
76812
+ headers: { "Content-Type": "application/json" },
76813
+ body: JSON.stringify(body)
76814
+ });
76815
+ const json = await resp.json();
76816
+ if (!resp.ok)
76817
+ throw OmniApiError.from(json, resp.status);
76818
+ return json?.data ?? {};
76819
+ }
76820
+ },
76408
76821
  agents: {
76409
76822
  async list(params) {
76410
76823
  const { data, error, response } = await client.GET("/agents", {
@@ -76465,183 +76878,7 @@ function createOmniClient(config) {
76465
76878
 
76466
76879
  // src/client.ts
76467
76880
  init_config();
76468
-
76469
- // src/output.ts
76470
- init_config();
76471
- var colorsEnabled = true;
76472
- function disableColors() {
76473
- colorsEnabled = false;
76474
- }
76475
- function areColorsEnabled() {
76476
- return colorsEnabled && process.stdout.isTTY !== false;
76477
- }
76478
- function c() {
76479
- if (areColorsEnabled()) {
76480
- return source_default;
76481
- }
76482
- return source_default;
76483
- }
76484
- function getCurrentFormat() {
76485
- return getOutputFormat();
76486
- }
76487
- function success(message, data) {
76488
- const format = getCurrentFormat();
76489
- if (format === "json") {
76490
- console.log(JSON.stringify({ success: true, message, data }, null, 2));
76491
- } else {
76492
- console.log(c().green("\u2713"), message);
76493
- if (data !== undefined) {
76494
- console.log(c().dim(JSON.stringify(data, null, 2)));
76495
- }
76496
- }
76497
- }
76498
- function error(message, details, exitCode = 1) {
76499
- const format = getCurrentFormat();
76500
- if (format === "json") {
76501
- console.error(JSON.stringify({ success: false, error: message, details }, null, 2));
76502
- } else {
76503
- console.error(c().red("\u2717"), message);
76504
- if (details !== undefined) {
76505
- console.error(c().dim(JSON.stringify(details, null, 2)));
76506
- }
76507
- }
76508
- process.exit(exitCode);
76509
- }
76510
- function warn(message) {
76511
- const format = getCurrentFormat();
76512
- if (format === "json") {
76513
- console.error(JSON.stringify({ warning: message }));
76514
- } else {
76515
- console.log(c().yellow("\u26A0"), message);
76516
- }
76517
- }
76518
- function info(message) {
76519
- const format = getCurrentFormat();
76520
- if (format === "json") {
76521
- console.error(JSON.stringify({ info: message }));
76522
- } else {
76523
- console.log(c().blue("\u2139"), message);
76524
- }
76525
- }
76526
- function data(value) {
76527
- const format = getCurrentFormat();
76528
- if (format === "json") {
76529
- console.log(JSON.stringify(value, null, 2));
76530
- } else {
76531
- if (Array.isArray(value)) {
76532
- printTable(value);
76533
- } else if (typeof value === "object" && value !== null) {
76534
- printObject(value);
76535
- } else {
76536
- console.log(value);
76537
- }
76538
- }
76539
- }
76540
- var maxCellWidth = 50;
76541
- function setMaxCellWidth(width) {
76542
- maxCellWidth = width;
76543
- }
76544
- function list(items, options) {
76545
- const format = getCurrentFormat();
76546
- if (format === "json") {
76547
- console.log(JSON.stringify(options?.rawData ?? items, null, 2));
76548
- return;
76549
- }
76550
- if (items.length === 0) {
76551
- console.log(c().dim(options?.emptyMessage ?? "No items found."));
76552
- return;
76553
- }
76554
- printTable(items);
76555
- }
76556
- function printTable(items) {
76557
- if (items.length === 0)
76558
- return;
76559
- const first = items[0];
76560
- if (typeof first !== "object" || first === null) {
76561
- for (const item of items) {
76562
- console.log(item);
76563
- }
76564
- return;
76565
- }
76566
- const keys = Object.keys(first);
76567
- if (keys.length === 0)
76568
- return;
76569
- const widths = {};
76570
- for (const key of keys) {
76571
- widths[key] = key.length;
76572
- }
76573
- for (const item of items) {
76574
- const obj = item;
76575
- for (const key of keys) {
76576
- const val = formatCellValue(obj[key]);
76577
- widths[key] = Math.max(widths[key], val.length);
76578
- }
76579
- }
76580
- const header = keys.map((k) => k.toUpperCase().padEnd(widths[k])).join(" ");
76581
- console.log(c().bold(header));
76582
- const separator = keys.map((k) => "-".repeat(widths[k])).join(" ");
76583
- console.log(c().dim(separator));
76584
- for (const item of items) {
76585
- const obj = item;
76586
- const row = keys.map((k) => formatCellValue(obj[k]).padEnd(widths[k])).join(" ");
76587
- console.log(row);
76588
- }
76589
- }
76590
- function formatCellValue(value) {
76591
- if (value === null || value === undefined) {
76592
- return "-";
76593
- }
76594
- if (typeof value === "boolean") {
76595
- return value ? "yes" : "no";
76596
- }
76597
- if (typeof value === "object") {
76598
- return JSON.stringify(value);
76599
- }
76600
- const str = String(value);
76601
- if (maxCellWidth > 0 && str.length > maxCellWidth) {
76602
- return `${str.slice(0, maxCellWidth - 3)}...`;
76603
- }
76604
- return str;
76605
- }
76606
- function printObject(obj) {
76607
- const maxKeyLen = Math.max(...Object.keys(obj).map((k) => k.length));
76608
- for (const [key, value] of Object.entries(obj)) {
76609
- const label = key.padEnd(maxKeyLen);
76610
- const formattedValue = formatValue(value);
76611
- console.log(`${c().cyan(label)} ${formattedValue}`);
76612
- }
76613
- }
76614
- function formatValue(value) {
76615
- if (value === null || value === undefined) {
76616
- return c().dim("-");
76617
- }
76618
- if (typeof value === "boolean") {
76619
- return value ? c().green("yes") : c().red("no");
76620
- }
76621
- if (typeof value === "object") {
76622
- return c().dim(JSON.stringify(value));
76623
- }
76624
- return String(value);
76625
- }
76626
- function header(title) {
76627
- if (getCurrentFormat() === "human") {
76628
- console.log(`
76629
- ${c().bold.underline(title)}`);
76630
- }
76631
- }
76632
- function dim(text) {
76633
- if (getCurrentFormat() === "human") {
76634
- console.log(c().dim(text));
76635
- }
76636
- }
76637
- function raw(text) {
76638
- console.log(text);
76639
- }
76640
- function flushStdout() {
76641
- return new Promise((resolve) => {
76642
- process.stdout.write("", () => resolve());
76643
- });
76644
- }
76881
+ init_output();
76645
76882
 
76646
76883
  // src/version.ts
76647
76884
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
@@ -76650,7 +76887,7 @@ import { fileURLToPath } from "url";
76650
76887
  // package.json
76651
76888
  var package_default = {
76652
76889
  name: "@automagik/omni",
76653
- version: "2.260404.1",
76890
+ version: "2.260405.2",
76654
76891
  description: "LLM-optimized CLI for Omni",
76655
76892
  type: "module",
76656
76893
  bin: {
@@ -76823,6 +77060,7 @@ function getOptionalClient() {
76823
77060
  }
76824
77061
 
76825
77062
  // src/commands/access.ts
77063
+ init_output();
76826
77064
  function createAccessCommand() {
76827
77065
  const access = new Command("access").description("Manage access control rules (allow/deny lists)");
76828
77066
  access.command("list").description("List access rules").option("--instance <id>", "Filter by instance ID").option("--type <type>", "Filter by rule type (allow, deny)").action(async (options) => {
@@ -76973,7 +77211,11 @@ function createAccessCommand() {
76973
77211
  return access;
76974
77212
  }
76975
77213
 
77214
+ // src/commands/agent-routes.ts
77215
+ init_output();
77216
+
76976
77217
  // src/resolve.ts
77218
+ init_output();
76977
77219
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
76978
77220
  async function resolveInstanceId(input) {
76979
77221
  if (UUID_RE.test(input))
@@ -77411,6 +77653,7 @@ function createRoutesCommand() {
77411
77653
  }
77412
77654
 
77413
77655
  // src/commands/agents.ts
77656
+ init_output();
77414
77657
  var VALID_PROVIDERS = ["claude", "agno", "openai", "gemini", "custom", "omni-internal"];
77415
77658
  var VALID_TYPES = ["assistant", "workflow", "team", "tool"];
77416
77659
  function createAgentsCommand() {
@@ -77496,8 +77739,10 @@ function createAgentsCommand() {
77496
77739
 
77497
77740
  // src/commands/auth.ts
77498
77741
  init_config();
77742
+ init_output();
77499
77743
 
77500
77744
  // src/pm2.ts
77745
+ init_output();
77501
77746
  var PM2_PROCESSES = {
77502
77747
  api: "omni-api",
77503
77748
  nats: "omni-nats"
@@ -77819,6 +78064,7 @@ function createAuthCommand() {
77819
78064
  }
77820
78065
 
77821
78066
  // src/commands/automations.ts
78067
+ init_output();
77822
78068
  function parseJson(json, fieldName) {
77823
78069
  try {
77824
78070
  return { ok: true, value: JSON.parse(json) };
@@ -78076,6 +78322,7 @@ function createAutomationsCommand() {
78076
78322
  }
78077
78323
 
78078
78324
  // src/commands/batch.ts
78325
+ init_output();
78079
78326
  function parseContentTypes(str) {
78080
78327
  if (!str)
78081
78328
  return;
@@ -78324,6 +78571,7 @@ function createBatchCommand() {
78324
78571
  // src/commands/channels.ts
78325
78572
  import * as readline from "readline";
78326
78573
  init_config();
78574
+ init_output();
78327
78575
  async function apiCall(path, method = "GET", body) {
78328
78576
  const config = loadConfig();
78329
78577
  const baseUrl = (config.apiUrl ?? "http://localhost:8882").replace(/\/$/, "");
@@ -78537,6 +78785,7 @@ async function addWhatsApp(channel, options) {
78537
78785
  }
78538
78786
 
78539
78787
  // src/commands/chats.ts
78788
+ init_output();
78540
78789
  var VALID_CHANNELS = ["whatsapp-baileys", "whatsapp-cloud", "discord", "slack", "telegram"];
78541
78790
  async function buildInstanceNameMap(client) {
78542
78791
  try {
@@ -79259,7 +79508,23 @@ function createChatsCommand() {
79259
79508
  return chats;
79260
79509
  }
79261
79510
 
79511
+ // src/commands/close.ts
79512
+ init_output();
79513
+ function createCloseCommand() {
79514
+ return new Command("close").description("Clear active conversation context").action(async () => {
79515
+ const client = getClient();
79516
+ try {
79517
+ await client.context.clear();
79518
+ } catch (err) {
79519
+ const message = err instanceof Error ? err.message : "Unknown error";
79520
+ return error(`Failed to clear context: ${message}`);
79521
+ }
79522
+ success("Conversation context cleared.");
79523
+ });
79524
+ }
79525
+
79262
79526
  // src/commands/completions.ts
79527
+ init_output();
79263
79528
  var BASH_COMPLETIONS = `
79264
79529
  # Omni CLI bash completion
79265
79530
  _omni_completions() {
@@ -79530,6 +79795,7 @@ Usage:`);
79530
79795
 
79531
79796
  // src/commands/config.ts
79532
79797
  init_config();
79798
+ init_output();
79533
79799
  function handleSetWithValue(key, value) {
79534
79800
  const keyMeta = CONFIG_KEYS[key];
79535
79801
  if (keyMeta.values && !keyMeta.values.includes(value)) {
@@ -79620,6 +79886,7 @@ function createConfigCommand() {
79620
79886
 
79621
79887
  // src/commands/connect.ts
79622
79888
  import { execFileSync } from "child_process";
79889
+ init_output();
79623
79890
  async function findOrCreateProvider(client, agentName, agentEntry, natsUrl) {
79624
79891
  try {
79625
79892
  const provider = await client.providers.create({
@@ -79718,6 +79985,7 @@ Make sure genie is installed and the agent is registered:
79718
79985
  }
79719
79986
 
79720
79987
  // src/commands/dead-letters.ts
79988
+ init_output();
79721
79989
  function createDeadLettersCommand() {
79722
79990
  const deadLetters = new Command("dead-letters").description("Manage failed events (dead letters)");
79723
79991
  deadLetters.command("list").description("List dead letters").option("--status <status>", "Filter by status (pending, retrying, resolved, abandoned)").option("--type <type>", "Filter by event type").option("--since <date>", 'Filter by date (ISO format or relative like "24h")').option("--limit <n>", "Limit results", (v) => Number.parseInt(v, 10), 20).action(async (options) => {
@@ -79806,8 +80074,197 @@ function createDeadLettersCommand() {
79806
80074
  return deadLetters;
79807
80075
  }
79808
80076
 
80077
+ // src/commands/done.ts
80078
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
80079
+ import { basename, extname } from "path";
80080
+
80081
+ // src/context.ts
80082
+ init_config();
80083
+ async function resolveContext(flags) {
80084
+ if (flags?.instance || flags?.chat || flags?.message) {
80085
+ return {
80086
+ instanceId: flags.instance ?? null,
80087
+ chatId: flags.chat ?? null,
80088
+ messageId: flags.message ?? null,
80089
+ source: "flags"
80090
+ };
80091
+ }
80092
+ const envInstance = process.env.OMNI_INSTANCE;
80093
+ const envChat = process.env.OMNI_CHAT;
80094
+ const envMessage = process.env.OMNI_MESSAGE;
80095
+ if (envInstance || envChat || envMessage) {
80096
+ return {
80097
+ instanceId: envInstance ?? null,
80098
+ chatId: envChat ?? null,
80099
+ messageId: envMessage ?? null,
80100
+ source: "env"
80101
+ };
80102
+ }
80103
+ try {
80104
+ const client = getClient();
80105
+ const ctx = await client.context.get();
80106
+ if (ctx.instanceId || ctx.chatId || ctx.messageId) {
80107
+ return {
80108
+ instanceId: ctx.instanceId,
80109
+ chatId: ctx.chatId,
80110
+ messageId: ctx.messageId,
80111
+ source: "api"
80112
+ };
80113
+ }
80114
+ } catch {}
80115
+ const config = loadConfig();
80116
+ if (config.defaultInstance) {
80117
+ return {
80118
+ instanceId: config.defaultInstance,
80119
+ chatId: null,
80120
+ messageId: null,
80121
+ source: "config"
80122
+ };
80123
+ }
80124
+ return {
80125
+ instanceId: null,
80126
+ chatId: null,
80127
+ messageId: null,
80128
+ source: "none"
80129
+ };
80130
+ }
80131
+ async function resolveInstanceFromContext(explicitInstance) {
80132
+ if (explicitInstance)
80133
+ return explicitInstance;
80134
+ const ctx = await resolveContext();
80135
+ if (ctx.instanceId)
80136
+ return ctx.instanceId;
80137
+ const output = await Promise.resolve().then(() => (init_output(), exports_output));
80138
+ return output.error("No instance specified. Use --instance, set OMNI_INSTANCE, or run: omni open <contact>");
80139
+ }
80140
+ async function resolveReplyTo(explicitMessageId) {
80141
+ if (explicitMessageId)
80142
+ return explicitMessageId;
80143
+ const envMessage = process.env.OMNI_MESSAGE;
80144
+ if (envMessage)
80145
+ return envMessage;
80146
+ try {
80147
+ const client = getClient();
80148
+ const ctx = await client.context.get();
80149
+ if (ctx.messageId)
80150
+ return ctx.messageId;
80151
+ } catch {}
80152
+ return null;
80153
+ }
80154
+
80155
+ // src/commands/done.ts
80156
+ init_output();
80157
+ function getMediaType(path) {
80158
+ const ext = extname(path).toLowerCase();
80159
+ const imageExts = [".jpg", ".jpeg", ".png", ".gif", ".webp"];
80160
+ const audioExts = [".mp3", ".wav", ".ogg", ".m4a", ".opus"];
80161
+ const videoExts = [".mp4", ".webm", ".mov", ".avi"];
80162
+ if (imageExts.includes(ext))
80163
+ return "image";
80164
+ if (audioExts.includes(ext))
80165
+ return "audio";
80166
+ if (videoExts.includes(ext))
80167
+ return "video";
80168
+ return "document";
80169
+ }
80170
+ async function closeTurn(client, action, successMsg, reason) {
80171
+ try {
80172
+ const result = await client.turns.close({ action, reason });
80173
+ if (result.alreadyClosed) {
80174
+ success(`${successMsg} Turn already closed (idempotent).`);
80175
+ } else {
80176
+ success(successMsg, { turnId: result.turnId, duration: result.duration });
80177
+ }
80178
+ } catch (err) {
80179
+ const message = err instanceof Error ? err.message : "Unknown error";
80180
+ error(`Failed to close turn: ${message}`);
80181
+ }
80182
+ }
80183
+ async function handleSkip(client, reason) {
80184
+ await closeTurn(client, "skip", "Turn closed (skip)", reason);
80185
+ }
80186
+ async function handleReact(client, ctx, emoji) {
80187
+ if (!ctx.messageId) {
80188
+ return error("No trigger message in context. Set OMNI_MESSAGE or use --message for --react.");
80189
+ }
80190
+ try {
80191
+ await client.messages.sendReaction({
80192
+ instanceId: ctx.instanceId,
80193
+ to: ctx.chatId,
80194
+ messageId: ctx.messageId,
80195
+ emoji
80196
+ });
80197
+ } catch (err) {
80198
+ const message = err instanceof Error ? err.message : "Unknown error";
80199
+ error(`Failed to send reaction: ${message}`);
80200
+ }
80201
+ await closeTurn(client, "react", `Reacted ${emoji} + turn closed`);
80202
+ }
80203
+ async function handleMedia(client, ctx, mediaPath, caption) {
80204
+ if (!existsSync3(mediaPath)) {
80205
+ return error(`File not found: ${mediaPath}`);
80206
+ }
80207
+ try {
80208
+ const mediaType = getMediaType(mediaPath);
80209
+ const buffer = readFileSync3(mediaPath);
80210
+ const base64 = buffer.toString("base64");
80211
+ const filename = basename(mediaPath);
80212
+ await client.messages.sendMedia({
80213
+ instanceId: ctx.instanceId,
80214
+ to: ctx.chatId,
80215
+ type: mediaType,
80216
+ base64,
80217
+ filename,
80218
+ caption
80219
+ });
80220
+ } catch (err) {
80221
+ const message = err instanceof Error ? err.message : "Unknown error";
80222
+ error(`Failed to send media: ${message}`);
80223
+ }
80224
+ await closeTurn(client, "message", "Media sent + turn closed");
80225
+ }
80226
+ async function handleText(client, ctx, text) {
80227
+ try {
80228
+ await client.messages.send({
80229
+ instanceId: ctx.instanceId,
80230
+ to: ctx.chatId,
80231
+ text
80232
+ });
80233
+ } catch (err) {
80234
+ const message = err instanceof Error ? err.message : "Unknown error";
80235
+ error(`Failed to send message: ${message}`);
80236
+ }
80237
+ await closeTurn(client, "message", "Message sent + turn closed");
80238
+ }
80239
+ function createDoneCommand() {
80240
+ return new Command("done").description("Close the current turn (send final message/reaction + emit turn.done)").argument("[text]", "Final text message to send before closing").option("--react <emoji>", "React to trigger message + close turn").option("--skip", "Close turn with no outbound message").option("--media <path>", "Send media file + close turn").option("--caption <text>", "Caption for media").option("--reason <text>", "Reason for closing (used with --skip)").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").option("--message <id>", "Override trigger message (default: from context)").action(async (text, options) => {
80241
+ const client = getClient();
80242
+ const ctx = await resolveContext({
80243
+ instance: options.instance,
80244
+ chat: options.chat,
80245
+ message: options.message
80246
+ });
80247
+ if (!ctx.instanceId) {
80248
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, or run: omni use <instance>");
80249
+ }
80250
+ if (!ctx.chatId) {
80251
+ return error("No chat in context. Set OMNI_CHAT, use --chat, or run: omni open <contact>");
80252
+ }
80253
+ if (options.skip)
80254
+ return handleSkip(client, options.reason);
80255
+ if (options.react)
80256
+ return handleReact(client, ctx, options.react);
80257
+ if (options.media)
80258
+ return handleMedia(client, ctx, options.media, options.caption);
80259
+ if (text)
80260
+ return handleText(client, ctx, text);
80261
+ error('Specify what to do: omni done "text", omni done --media <file>, omni done --react <emoji>, or omni done --skip');
80262
+ });
80263
+ }
80264
+
79809
80265
  // src/commands/events.ts
79810
80266
  init_config();
80267
+ init_output();
79811
80268
  function parseSinceTime(since) {
79812
80269
  const match = since.match(/^(\d+)([hdwm]|min)$/);
79813
80270
  if (!match) {
@@ -80043,13 +80500,12 @@ function createEventsCommand() {
80043
80500
  return events;
80044
80501
  }
80045
80502
 
80046
- // src/commands/install.ts
80047
- import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
80048
- import { homedir as homedir2 } from "os";
80049
- import { join as join4 } from "path";
80050
- import { createInterface as createInterface2 } from "readline";
80503
+ // src/commands/film.ts
80504
+ import { writeFileSync as writeFileSync2 } from "fs";
80505
+ import { resolve as resolvePath } from "path";
80051
80506
 
80052
80507
  // ../../node_modules/.bun/ora@8.2.0/node_modules/ora/index.js
80508
+ init_source();
80053
80509
  import process9 from "process";
80054
80510
 
80055
80511
  // ../../node_modules/.bun/cli-cursor@5.0.0/node_modules/cli-cursor/index.js
@@ -80385,6 +80841,9 @@ var cli_cursor_default = cliCursor;
80385
80841
  // ../../node_modules/.bun/ora@8.2.0/node_modules/ora/index.js
80386
80842
  var import_cli_spinners = __toESM(require_cli_spinners(), 1);
80387
80843
 
80844
+ // ../../node_modules/.bun/log-symbols@6.0.0/node_modules/log-symbols/index.js
80845
+ init_source();
80846
+
80388
80847
  // ../../node_modules/.bun/is-unicode-supported@1.3.0/node_modules/is-unicode-supported/index.js
80389
80848
  import process6 from "process";
80390
80849
  function isUnicodeSupported() {
@@ -80928,7 +81387,233 @@ function ora(options) {
80928
81387
  return new Ora(options);
80929
81388
  }
80930
81389
 
81390
+ // src/commands/film.ts
81391
+ init_output();
81392
+ function createFilmCommand() {
81393
+ return new Command("film").description("Generate a video from a text prompt (Gemini Veo 3.1)").argument("<prompt>", "Text prompt describing the video").option("--duration <seconds>", "Clip duration in seconds (provider-dependent max)").option("--resolution <res>", "Resolution hint (720p or 1080p)").option("--aspect-ratio <ratio>", "Aspect ratio (16:9 or 9:16)", "16:9").option("--reference <path>", "Reference image path (reserved for future use)").option("--extend <operationId>", "Extend an existing video operation (reserved for future use)").option("--seed <number>", "RNG seed for reproducible output").option("--no-audio", "Disable audio generation").option("-o, --output <path>", "Save video to file locally (does not send)").option("--reply [message-id]", "Quote-reply to trigger message or specific message ID").option("--provider <name>", "Video generation provider (default: gemini)").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").action(async (prompt, options) => {
81394
+ const client = getClient();
81395
+ const saveOnly = Boolean(options.output);
81396
+ let instanceId;
81397
+ let chatId;
81398
+ let replyTo;
81399
+ if (!saveOnly) {
81400
+ const ctx = await resolveContext({
81401
+ instance: options.instance,
81402
+ chat: options.chat
81403
+ });
81404
+ if (!ctx.instanceId) {
81405
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, --output, or run: omni use <instance>");
81406
+ }
81407
+ if (!ctx.chatId) {
81408
+ return error("No chat in context. Set OMNI_CHAT, use --chat, --output, or run: omni open <contact>");
81409
+ }
81410
+ instanceId = ctx.instanceId;
81411
+ chatId = ctx.chatId;
81412
+ if (options.reply !== undefined) {
81413
+ const replyId = typeof options.reply === "string" ? options.reply : undefined;
81414
+ const resolved = await resolveReplyTo(replyId);
81415
+ if (!resolved) {
81416
+ return error("No message to reply to. Set OMNI_MESSAGE, use --reply <id>, or run: omni open <contact>");
81417
+ }
81418
+ replyTo = resolved;
81419
+ }
81420
+ }
81421
+ const durationSec = options.duration ? Number.parseInt(options.duration, 10) : undefined;
81422
+ if (options.duration !== undefined && Number.isNaN(durationSec)) {
81423
+ return error(`Invalid --duration value: ${options.duration}`);
81424
+ }
81425
+ const seed = options.seed ? Number.parseInt(options.seed, 10) : undefined;
81426
+ if (options.seed !== undefined && Number.isNaN(seed)) {
81427
+ return error(`Invalid --seed value: ${options.seed}`);
81428
+ }
81429
+ const spinner = ora({
81430
+ text: "Submitting video generation request\u2026",
81431
+ isEnabled: getCurrentFormat() === "human"
81432
+ }).start();
81433
+ const startTime = Date.now();
81434
+ const tick = setInterval(() => {
81435
+ const seconds = Math.floor((Date.now() - startTime) / 1000);
81436
+ spinner.text = `Generating video via Veo 3.1\u2026 ${seconds}s elapsed`;
81437
+ }, 1000);
81438
+ try {
81439
+ const result = await client.media.film({
81440
+ prompt,
81441
+ provider: options.provider,
81442
+ durationSec,
81443
+ resolution: options.resolution,
81444
+ aspectRatio: options.aspectRatio,
81445
+ seed,
81446
+ audio: options.audio !== false
81447
+ });
81448
+ clearInterval(tick);
81449
+ spinner.succeed(`Video ready (${result.sizeBytes} bytes, ${result.mimeType})`);
81450
+ const videoBuffer = Buffer.from(result.videoBase64, "base64");
81451
+ if (options.output) {
81452
+ const outPath = resolvePath(options.output);
81453
+ writeFileSync2(outPath, videoBuffer);
81454
+ success("Video saved", { path: outPath, sizeBytes: videoBuffer.length });
81455
+ return;
81456
+ }
81457
+ const filename = `film-${Date.now()}.mp4`;
81458
+ const sent = await client.messages.sendMedia({
81459
+ instanceId,
81460
+ to: chatId,
81461
+ type: "video",
81462
+ base64: result.videoBase64,
81463
+ filename,
81464
+ caption: prompt
81465
+ });
81466
+ success("Video sent", { ...sent, filename, sizeBytes: videoBuffer.length });
81467
+ } catch (err) {
81468
+ clearInterval(tick);
81469
+ spinner.fail("Video generation failed");
81470
+ const message = err instanceof Error ? err.message : "Unknown error";
81471
+ error(`omni film: ${message}`);
81472
+ }
81473
+ });
81474
+ }
81475
+
81476
+ // src/commands/imagine.ts
81477
+ import { writeFileSync as writeFileSync3 } from "fs";
81478
+ import { basename as basename2, dirname as dirname2, extname as extname2, join as join3 } from "path";
81479
+ init_output();
81480
+ var ALLOWED_ASPECT_RATIOS = ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3"];
81481
+ function extensionForMime(mimeType) {
81482
+ if (mimeType.includes("jpeg") || mimeType.includes("jpg"))
81483
+ return ".jpg";
81484
+ if (mimeType.includes("webp"))
81485
+ return ".webp";
81486
+ return ".png";
81487
+ }
81488
+ function buildOutputPath(outputBase, index, total, mimeType) {
81489
+ const dir = dirname2(outputBase);
81490
+ const ext = extname2(outputBase) || extensionForMime(mimeType);
81491
+ const stem = basename2(outputBase, extname2(outputBase));
81492
+ if (total <= 1) {
81493
+ return join3(dir, `${stem}${ext}`);
81494
+ }
81495
+ return join3(dir, `${stem}-${index + 1}${ext}`);
81496
+ }
81497
+ function parseAspectRatio(value) {
81498
+ if (!value)
81499
+ return;
81500
+ if (!ALLOWED_ASPECT_RATIOS.includes(value)) {
81501
+ error(`Invalid --aspect-ratio "${value}". Allowed: ${ALLOWED_ASPECT_RATIOS.join(", ")}`);
81502
+ }
81503
+ return value;
81504
+ }
81505
+ function createImagineCommand() {
81506
+ return new Command("imagine").description("Generate an image from a text prompt (Gemini Nano Banana) and send or save it").argument("<prompt...>", "Prompt describing the image to generate").option("--aspect-ratio <ratio>", "Aspect ratio (1:1, 3:4, 4:3, 9:16, 16:9, 3:2, 2:3)").option("--size <size>", "Image size preset (1K, 2K, 4K \u2014 not all models support all sizes)").option("--model <name>", "Model alias (nano-banana-2, nano-banana-pro) or raw Gemini model ID").option("--provider <name>", "Provider override (default: config imagegen.provider)").option("--count <n>", "Number of images to generate (1-4)", "1").option("--output <path>", "Save locally instead of sending (appends -N for count > 1)").option("--reply [message-id]", "Quote-reply to the trigger message or a specific message ID").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").action(async (promptParts, options) => {
81507
+ const prompt = promptParts.join(" ").trim();
81508
+ if (!prompt) {
81509
+ return error('Prompt is required. Example: omni imagine "a neon cat in Tokyo"');
81510
+ }
81511
+ const count = Number.parseInt(options.count ?? "1", 10);
81512
+ if (Number.isNaN(count) || count < 1 || count > 4) {
81513
+ return error("--count must be an integer between 1 and 4");
81514
+ }
81515
+ const aspectRatio = parseAspectRatio(options.aspectRatio);
81516
+ const saveLocally = !!options.output;
81517
+ let instanceId;
81518
+ let chatId;
81519
+ let replyTo;
81520
+ if (!saveLocally) {
81521
+ const ctx = await resolveContext({
81522
+ instance: options.instance,
81523
+ chat: options.chat
81524
+ });
81525
+ if (!ctx.instanceId) {
81526
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, --output, or run: omni use <instance>");
81527
+ }
81528
+ if (!ctx.chatId) {
81529
+ return error("No chat in context. Set OMNI_CHAT, use --chat, --output, or run: omni open <contact>");
81530
+ }
81531
+ instanceId = ctx.instanceId;
81532
+ chatId = ctx.chatId;
81533
+ if (options.reply !== undefined) {
81534
+ const explicitReplyId = typeof options.reply === "string" ? options.reply : undefined;
81535
+ const resolved = await resolveReplyTo(explicitReplyId);
81536
+ if (!resolved) {
81537
+ return error("No message to reply to. Set OMNI_MESSAGE, use --reply <id>, or run: omni open <contact>");
81538
+ }
81539
+ replyTo = resolved;
81540
+ }
81541
+ }
81542
+ const client = getClient();
81543
+ let result;
81544
+ try {
81545
+ result = await client.media.imagine({
81546
+ prompt,
81547
+ provider: options.provider,
81548
+ count,
81549
+ aspectRatio,
81550
+ imageSize: options.size,
81551
+ model: options.model
81552
+ });
81553
+ } catch (err) {
81554
+ const message = err instanceof Error ? err.message : "Unknown error";
81555
+ return error(`Image generation failed: ${message}`);
81556
+ }
81557
+ if (!result.images || result.images.length === 0) {
81558
+ return error("API returned no images");
81559
+ }
81560
+ if (saveLocally && options.output) {
81561
+ const savedPaths = [];
81562
+ for (let i = 0;i < result.images.length; i++) {
81563
+ const image = result.images[i];
81564
+ if (!image)
81565
+ continue;
81566
+ const path = buildOutputPath(options.output, i, result.images.length, image.mimeType);
81567
+ try {
81568
+ writeFileSync3(path, Buffer.from(image.base64, "base64"));
81569
+ savedPaths.push(path);
81570
+ } catch (err) {
81571
+ const message = err instanceof Error ? err.message : "Unknown error";
81572
+ return error(`Failed to write ${path}: ${message}`);
81573
+ }
81574
+ }
81575
+ return success(`Generated ${savedPaths.length} image(s) via ${result.provider}`, {
81576
+ provider: result.provider,
81577
+ processingMs: result.processingMs,
81578
+ paths: savedPaths
81579
+ });
81580
+ }
81581
+ const sent = [];
81582
+ for (let i = 0;i < result.images.length; i++) {
81583
+ const image = result.images[i];
81584
+ if (!image)
81585
+ continue;
81586
+ const filename = result.images.length > 1 ? `imagine-${Date.now()}-${i + 1}.png` : `imagine-${Date.now()}.png`;
81587
+ try {
81588
+ const res = await client.messages.sendMedia({
81589
+ instanceId,
81590
+ to: chatId,
81591
+ type: "image",
81592
+ base64: image.base64,
81593
+ filename,
81594
+ caption: i === 0 ? prompt : undefined
81595
+ });
81596
+ sent.push({ messageId: res.messageId, index: i });
81597
+ } catch (err) {
81598
+ const message = err instanceof Error ? err.message : "Unknown error";
81599
+ return error(`Failed to send image ${i + 1}: ${message}`);
81600
+ }
81601
+ }
81602
+ success(`Generated and sent ${sent.length} image(s) via ${result.provider}`, {
81603
+ provider: result.provider,
81604
+ processingMs: result.processingMs,
81605
+ instanceId,
81606
+ chatId,
81607
+ sent
81608
+ });
81609
+ });
81610
+ }
81611
+
80931
81612
  // src/commands/install.ts
81613
+ import { chmodSync, existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync4 } from "fs";
81614
+ import { homedir as homedir2 } from "os";
81615
+ import { join as join5 } from "path";
81616
+ import { createInterface as createInterface2 } from "readline";
80932
81617
  init_config();
80933
81618
 
80934
81619
  // src/health.ts
@@ -80952,25 +81637,29 @@ async function waitForHealth(port, timeoutMs = HEALTH_TIMEOUT_MS) {
80952
81637
  return false;
80953
81638
  }
80954
81639
 
81640
+ // src/commands/install.ts
81641
+ init_output();
81642
+
80955
81643
  // src/server-bundle.ts
80956
- import { dirname as dirname2, join as join3 } from "path";
81644
+ init_output();
81645
+ import { dirname as dirname3, join as join4 } from "path";
80957
81646
  import { fileURLToPath as fileURLToPath2 } from "url";
80958
81647
  function getServerBundlePath() {
80959
81648
  try {
80960
81649
  const thisFile = fileURLToPath2(import.meta.url);
80961
- const distDir = dirname2(thisFile);
80962
- return join3(distDir, "server", "index.js");
81650
+ const distDir = dirname3(thisFile);
81651
+ return join4(distDir, "server", "index.js");
80963
81652
  } catch {
80964
- return join3(process.cwd(), "dist", "server", "index.js");
81653
+ return join4(process.cwd(), "dist", "server", "index.js");
80965
81654
  }
80966
81655
  }
80967
81656
  function getServerLauncherPath() {
80968
81657
  try {
80969
81658
  const thisFile = fileURLToPath2(import.meta.url);
80970
- const distDir = dirname2(thisFile);
80971
- return join3(distDir, "..", "bin", "omni-server");
81659
+ const distDir = dirname3(thisFile);
81660
+ return join4(distDir, "..", "bin", "omni-server");
80972
81661
  } catch {
80973
- return join3(process.cwd(), "bin", "omni-server");
81662
+ return join4(process.cwd(), "bin", "omni-server");
80974
81663
  }
80975
81664
  }
80976
81665
  function bundleNotFoundError(bundlePath) {
@@ -80981,10 +81670,10 @@ function bundleNotFoundError(bundlePath) {
80981
81670
  }
80982
81671
 
80983
81672
  // src/commands/install.ts
80984
- var DEFAULT_DATA_DIR = join4(homedir2(), ".omni", "data");
81673
+ var DEFAULT_DATA_DIR = join5(homedir2(), ".omni", "data");
80985
81674
  var DEFAULT_DATABASE_URL = process.env.DATABASE_URL ?? "postgresql://postgres:postgres@localhost:5432/omni";
80986
- var OMNI_DIR = join4(homedir2(), ".omni");
80987
- var NATS_BINARY_PATH = join4(OMNI_DIR, "nats-server");
81675
+ var OMNI_DIR = join5(homedir2(), ".omni");
81676
+ var NATS_BINARY_PATH = join5(OMNI_DIR, "nats-server");
80988
81677
  var NATS_VERSION = "v2.12.4";
80989
81678
  async function isBunAvailable() {
80990
81679
  try {
@@ -81053,10 +81742,10 @@ async function downloadNats() {
81053
81742
  return false;
81054
81743
  }
81055
81744
  const arrayBuf = await resp.arrayBuffer();
81056
- const tarPath = join4(OMNI_DIR, fileName);
81057
- writeFileSync2(tarPath, Buffer.from(arrayBuf));
81745
+ const tarPath = join5(OMNI_DIR, fileName);
81746
+ writeFileSync4(tarPath, Buffer.from(arrayBuf));
81058
81747
  spinner.text = "Extracting NATS binary...";
81059
- const tmpDir = join4(OMNI_DIR, "nats-tmp");
81748
+ const tmpDir = join5(OMNI_DIR, "nats-tmp");
81060
81749
  mkdirSync2(tmpDir, { recursive: true });
81061
81750
  const tarProc = Bun.spawn({
81062
81751
  cmd: ["tar", "-xzf", tarPath, "-C", tmpDir],
@@ -81132,10 +81821,10 @@ function buildApiRuntimeEnv(cfg) {
81132
81821
  API_PORT: String(cfg.port),
81133
81822
  DATABASE_URL: cfg.databaseUrl,
81134
81823
  OMNI_API_KEY: cfg.apiKey,
81135
- MEDIA_STORAGE_PATH: join4(cfg.dataDir, "media"),
81136
- OMNI_PACKAGES_DIR: join4(cfg.dataDir, "packages"),
81824
+ MEDIA_STORAGE_PATH: join5(cfg.dataDir, "media"),
81825
+ OMNI_PACKAGES_DIR: join5(cfg.dataDir, "packages"),
81137
81826
  PGSERVE_EMBEDDED: "true",
81138
- PGSERVE_DATA: join4(cfg.dataDir, "pgserve"),
81827
+ PGSERVE_DATA: join5(cfg.dataDir, "pgserve"),
81139
81828
  NATS_URL: "nats://localhost:4222",
81140
81829
  NODE_ENV: "production",
81141
81830
  LOG_LEVEL: "info"
@@ -81164,7 +81853,7 @@ After=network.target
81164
81853
 
81165
81854
  [Service]
81166
81855
  Type=simple
81167
- ExecStart="${NATS_BINARY_PATH}" -js -sd "${join4(_cfg.dataDir, "nats")}"
81856
+ ExecStart="${NATS_BINARY_PATH}" -js -sd "${join5(_cfg.dataDir, "nats")}"
81168
81857
  Restart=on-failure
81169
81858
  RestartSec=5
81170
81859
 
@@ -81174,9 +81863,9 @@ WantedBy=multi-user.target
81174
81863
  const apiPath = "/etc/systemd/system/omni-api.service";
81175
81864
  const natsPath = "/etc/systemd/system/omni-nats.service";
81176
81865
  try {
81177
- writeFileSync2(natsPath, natsUnit, { mode: 420 });
81866
+ writeFileSync4(natsPath, natsUnit, { mode: 420 });
81178
81867
  success(`Systemd unit written to ${natsPath}`);
81179
- writeFileSync2(apiPath, apiUnit, { mode: 420 });
81868
+ writeFileSync4(apiPath, apiUnit, { mode: 420 });
81180
81869
  success(`Systemd unit written to ${apiPath}`);
81181
81870
  raw(`
81182
81871
  Enable and start with:`);
@@ -81214,7 +81903,7 @@ async function runSystemChecks(port) {
81214
81903
  return { bunOk, portOk };
81215
81904
  }
81216
81905
  async function ensureNats() {
81217
- if (existsSync3(NATS_BINARY_PATH)) {
81906
+ if (existsSync4(NATS_BINARY_PATH)) {
81218
81907
  raw(` \u2713 NATS binary found at ${NATS_BINARY_PATH}`);
81219
81908
  return;
81220
81909
  }
@@ -81283,7 +81972,7 @@ async function startServices(cfg) {
81283
81972
  return;
81284
81973
  }
81285
81974
  const bundlePath = getServerBundlePath();
81286
- if (!existsSync3(bundlePath)) {
81975
+ if (!existsSync4(bundlePath)) {
81287
81976
  warn(`Server bundle not found at: ${bundlePath}
81288
81977
  Install @automagik/omni from npm: bun add -g @automagik/omni
81289
81978
  Or build locally: make cli-build-full`);
@@ -81298,9 +81987,9 @@ async function startServices(cfg) {
81298
81987
  } else {
81299
81988
  apiSpinner.succeed(`${PM2_PROCESSES.api} started`);
81300
81989
  }
81301
- if (existsSync3(NATS_BINARY_PATH)) {
81990
+ if (existsSync4(NATS_BINARY_PATH)) {
81302
81991
  const natsSpinner = ora(`Starting ${PM2_PROCESSES.nats}...`).start();
81303
- const natsDataDir = join4(cfg.dataDir, "nats");
81992
+ const natsDataDir = join5(cfg.dataDir, "nats");
81304
81993
  mkdirSync2(natsDataDir, { recursive: true });
81305
81994
  const natsCode = await runPm2([
81306
81995
  "start",
@@ -81338,7 +82027,7 @@ function writeConfigFile(port, apiKey) {
81338
82027
  format: "human"
81339
82028
  };
81340
82029
  saveConfig(config);
81341
- success(`Config written to ${join4(homedir2(), ".omni", "config.json")}`);
82030
+ success(`Config written to ${join5(homedir2(), ".omni", "config.json")}`);
81342
82031
  }
81343
82032
  async function printDoneBanner(port, apiKey, nonInteractive, showFullGeneratedKey) {
81344
82033
  const displayedKey = showFullGeneratedKey ? apiKey : maskApiKey(apiKey);
@@ -81401,6 +82090,7 @@ function createInstallCommand() {
81401
82090
 
81402
82091
  // src/commands/instances.ts
81403
82092
  var import_qrcode_terminal = __toESM(require_main(), 1);
82093
+ init_output();
81404
82094
  var VALID_CHANNELS2 = ["whatsapp-baileys", "whatsapp-cloud", "discord", "slack", "telegram", "gupshup"];
81405
82095
  var VALID_SYNC_TYPES = ["profile", "messages", "contacts", "groups", "all"];
81406
82096
  function setVal(body, key, val) {
@@ -82177,7 +82867,9 @@ function createInstancesCommand() {
82177
82867
  }
82178
82868
 
82179
82869
  // src/commands/journey.ts
82870
+ init_source();
82180
82871
  init_config();
82872
+ init_output();
82181
82873
  var STAGE_LABELS = {
82182
82874
  T0: "Platform received",
82183
82875
  T1: "Plugin received",
@@ -82391,6 +83083,7 @@ function createJourneyCommand() {
82391
83083
  }
82392
83084
 
82393
83085
  // src/commands/keys.ts
83086
+ init_output();
82394
83087
  function formatKeyRow(key) {
82395
83088
  return {
82396
83089
  id: key.id.slice(0, 8),
@@ -82546,7 +83239,133 @@ function createKeysCommand() {
82546
83239
  return keys;
82547
83240
  }
82548
83241
 
83242
+ // src/commands/listen.ts
83243
+ import { readFile } from "fs/promises";
83244
+ import { basename as basename3, extname as extname3 } from "path";
83245
+ init_output();
83246
+ var ALLOWED_FORMATS = ["text", "json"];
83247
+ function parseFormat(value) {
83248
+ if (!value)
83249
+ return "text";
83250
+ const normalized = value.toLowerCase();
83251
+ if (!ALLOWED_FORMATS.includes(normalized)) {
83252
+ error(`Invalid --format "${value}". Allowed: ${ALLOWED_FORMATS.join(", ")}`);
83253
+ }
83254
+ return normalized;
83255
+ }
83256
+ function guessAudioMimeType(filePath) {
83257
+ const ext = extname3(filePath).toLowerCase().slice(1);
83258
+ switch (ext) {
83259
+ case "ogg":
83260
+ case "oga":
83261
+ return "audio/ogg";
83262
+ case "opus":
83263
+ return "audio/ogg";
83264
+ case "mp3":
83265
+ return "audio/mpeg";
83266
+ case "wav":
83267
+ return "audio/wav";
83268
+ case "flac":
83269
+ return "audio/flac";
83270
+ case "aac":
83271
+ return "audio/aac";
83272
+ case "m4a":
83273
+ return "audio/mp4";
83274
+ case "mp4":
83275
+ return "audio/mp4";
83276
+ case "webm":
83277
+ return "audio/webm";
83278
+ case "aiff":
83279
+ case "aif":
83280
+ return "audio/aiff";
83281
+ default:
83282
+ return "audio/ogg";
83283
+ }
83284
+ }
83285
+ function createListenCommand() {
83286
+ return new Command("listen").description("Transcribe an audio file to text and print (or send as reply)").argument("<file>", "Path to the audio file to transcribe").option("--provider <name>", "STT provider (gemini, groq). Default: server config.").option("--language <code>", "BCP-47 language hint (e.g. en, pt-BR)").option("--timestamps", "Include per-segment timestamps").option("--format <fmt>", `Output format: ${ALLOWED_FORMATS.join(", ")} (default: text)`).option("--model <name>", "Model override (provider-specific)").option("--reply [message-id]", "Send transcript as a quote-reply to the trigger or a specific message").option("--instance <id>", "Override instance (default: from context, only with --reply)").option("--chat <id>", "Override chat (default: from context, only with --reply)").action(async (file, options) => {
83287
+ const client = getClient();
83288
+ const format = parseFormat(options.format);
83289
+ const wantTimestamps = options.timestamps === true;
83290
+ let audioBuffer;
83291
+ try {
83292
+ audioBuffer = await readFile(file);
83293
+ } catch (err) {
83294
+ const message = err instanceof Error ? err.message : "Unknown error";
83295
+ return error(`Failed to read ${file}: ${message}`);
83296
+ }
83297
+ if (audioBuffer.length === 0) {
83298
+ return error(`File is empty: ${file}`);
83299
+ }
83300
+ const mimeType = guessAudioMimeType(file);
83301
+ let result;
83302
+ try {
83303
+ result = await client.media.stt({
83304
+ audio: audioBuffer,
83305
+ mimeType,
83306
+ provider: options.provider,
83307
+ language: options.language,
83308
+ timestamps: wantTimestamps,
83309
+ model: options.model
83310
+ });
83311
+ } catch (err) {
83312
+ const message = err instanceof Error ? err.message : "Unknown error";
83313
+ return error(`STT transcription failed: ${message}`);
83314
+ }
83315
+ if (options.reply !== undefined) {
83316
+ const ctx = await resolveContext({
83317
+ instance: options.instance,
83318
+ chat: options.chat
83319
+ });
83320
+ if (!ctx.instanceId) {
83321
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, or run: omni use <instance>");
83322
+ }
83323
+ if (!ctx.chatId) {
83324
+ return error("No chat in context. Set OMNI_CHAT, use --chat, or run: omni open <contact>");
83325
+ }
83326
+ const replyId = typeof options.reply === "string" ? options.reply : undefined;
83327
+ const resolvedReply = await resolveReplyTo(replyId);
83328
+ if (!resolvedReply) {
83329
+ return error("No message to reply to. Set OMNI_MESSAGE, use --reply <id>, or run: omni open <contact>");
83330
+ }
83331
+ try {
83332
+ const sendResult = await client.messages.send({
83333
+ instanceId: ctx.instanceId,
83334
+ to: ctx.chatId,
83335
+ text: result.text,
83336
+ replyTo: resolvedReply
83337
+ });
83338
+ return success("Transcription sent as reply", {
83339
+ provider: result.provider,
83340
+ file: basename3(file),
83341
+ sizeKb: Math.round(audioBuffer.length / 1024 * 100) / 100,
83342
+ processingMs: result.processingMs,
83343
+ text: result.text,
83344
+ ...sendResult
83345
+ });
83346
+ } catch (err) {
83347
+ const message = err instanceof Error ? err.message : "Unknown error";
83348
+ return error(`Failed to send transcription reply: ${message}`);
83349
+ }
83350
+ }
83351
+ if (format === "json") {
83352
+ return success("Transcription complete", {
83353
+ provider: result.provider,
83354
+ file: basename3(file),
83355
+ mimeType,
83356
+ sizeKb: Math.round(audioBuffer.length / 1024 * 100) / 100,
83357
+ processingMs: result.processingMs,
83358
+ detectedLanguage: result.detectedLanguage,
83359
+ text: result.text,
83360
+ segments: result.segments
83361
+ });
83362
+ }
83363
+ console.log(result.text);
83364
+ });
83365
+ }
83366
+
82549
83367
  // src/commands/logs.ts
83368
+ init_output();
82550
83369
  async function streamProcessLogs(service, lines, follow) {
82551
83370
  if (!await isPm2Available()) {
82552
83371
  pm2NotFoundError();
@@ -82597,11 +83416,12 @@ function createLogsCommand() {
82597
83416
  }
82598
83417
 
82599
83418
  // src/commands/media.ts
82600
- import { createWriteStream, existsSync as existsSync4, mkdirSync as mkdirSync3, statSync } from "fs";
82601
- import { basename, dirname as dirname3, resolve } from "path";
83419
+ import { createWriteStream, existsSync as existsSync5, mkdirSync as mkdirSync3, statSync } from "fs";
83420
+ import { basename as basename4, dirname as dirname4, resolve } from "path";
82602
83421
  import { Readable } from "stream";
82603
83422
  import { pipeline } from "stream/promises";
82604
83423
  init_config();
83424
+ init_output();
82605
83425
  function buildUrl(baseUrl, path, query) {
82606
83426
  let url = `${baseUrl}/api/v2/${path}`;
82607
83427
  if (!query)
@@ -82651,7 +83471,7 @@ function resolveDownloadUrl(baseUrl, downloadUrl) {
82651
83471
  return `${base}${path}`;
82652
83472
  }
82653
83473
  function resolveOutputPath(outputPath, result) {
82654
- const fallbackName = result.mediaLocalPath ? basename(result.mediaLocalPath) : "";
83474
+ const fallbackName = result.mediaLocalPath ? basename4(result.mediaLocalPath) : "";
82655
83475
  const filename = fallbackName || `${result.messageId}`;
82656
83476
  if (!outputPath)
82657
83477
  return resolve(process.cwd(), filename);
@@ -82659,13 +83479,13 @@ function resolveOutputPath(outputPath, result) {
82659
83479
  const resolved = resolve(outputPath);
82660
83480
  if (isDirHint)
82661
83481
  return resolve(resolved, filename);
82662
- if (existsSync4(resolved) && statSync(resolved).isDirectory())
83482
+ if (existsSync5(resolved) && statSync(resolved).isDirectory())
82663
83483
  return resolve(resolved, filename);
82664
83484
  return resolved;
82665
83485
  }
82666
83486
  async function downloadToFile(url, apiKey, destinationPath) {
82667
- const destDir = dirname3(destinationPath);
82668
- if (!existsSync4(destDir))
83487
+ const destDir = dirname4(destinationPath);
83488
+ if (!existsSync5(destDir))
82669
83489
  mkdirSync3(destDir, { recursive: true });
82670
83490
  const resp = await fetch(url, {
82671
83491
  method: "GET",
@@ -82867,6 +83687,7 @@ function createMediaCommand() {
82867
83687
  }
82868
83688
 
82869
83689
  // src/commands/messages.ts
83690
+ init_output();
82870
83691
  function parseDuration(duration) {
82871
83692
  const now = new Date;
82872
83693
  const match = duration.match(/^(\d+)([dhm])$/);
@@ -83198,7 +84019,37 @@ function createMessagesCommand() {
83198
84019
  return messages;
83199
84020
  }
83200
84021
 
84022
+ // src/commands/open.ts
84023
+ init_output();
84024
+ function createOpenCommand() {
84025
+ return new Command("open").description("Open a conversation context (set active chat for verb commands)").argument("<contact>", "Contact name, phone number, or chat ID").option("--instance <id>", "Instance to use (default: resolved from context)").action(async (contact, options) => {
84026
+ const client = getClient();
84027
+ let instanceId;
84028
+ try {
84029
+ instanceId = await resolveInstanceFromContext(options.instance);
84030
+ instanceId = await resolveInstanceId(instanceId);
84031
+ } catch {
84032
+ return error("Could not resolve instance. Use --instance or run: omni use <instance>");
84033
+ }
84034
+ let chatId;
84035
+ try {
84036
+ chatId = await resolveChatId(contact);
84037
+ } catch {
84038
+ return error(`Could not resolve contact "${contact}". Try a chat ID, name, or phone number.`);
84039
+ }
84040
+ try {
84041
+ await client.context.set({ instanceId, chatId });
84042
+ } catch (err) {
84043
+ const message = err instanceof Error ? err.message : "Unknown error";
84044
+ return error(`Failed to set context: ${message}`);
84045
+ }
84046
+ success(`Opened conversation ${chatId.slice(0, 8)}\u2026 on instance ${instanceId.slice(0, 8)}\u2026`);
84047
+ dim("Verb commands (say, send, react, etc.) will now target this chat.");
84048
+ });
84049
+ }
84050
+
83201
84051
  // src/commands/payloads.ts
84052
+ init_output();
83202
84053
  var VALID_STAGES = ["webhook_raw", "agent_request", "agent_response", "channel_send", "error"];
83203
84054
  var boolDisplay = (v) => v ? "yes" : "no";
83204
84055
  var parseBool = (v) => v === "true" ? true : v === "false" ? false : undefined;
@@ -83301,6 +84152,7 @@ function createPayloadsCommand() {
83301
84152
  }
83302
84153
 
83303
84154
  // src/commands/persons.ts
84155
+ init_output();
83304
84156
  function createPersonsCommand() {
83305
84157
  const persons = new Command("persons").description("Search and manage persons");
83306
84158
  persons.command("search <query>").description("Search for persons").option("--limit <n>", "Limit results", (v) => Number.parseInt(v, 10), 20).action(async (query, options) => {
@@ -83310,7 +84162,8 @@ function createPersonsCommand() {
83310
84162
  search: query,
83311
84163
  limit: options.limit
83312
84164
  });
83313
- const items = results.map((p) => ({
84165
+ const persons2 = results;
84166
+ const items = persons2.map((p) => ({
83314
84167
  id: p.id,
83315
84168
  displayName: p.displayName ?? "-",
83316
84169
  email: p.email ?? "-",
@@ -83344,10 +84197,77 @@ function createPersonsCommand() {
83344
84197
  error(`Failed to get presence: ${message}`, undefined, 3);
83345
84198
  }
83346
84199
  });
84200
+ persons.command("update <id>").description("Update person fields").option("--name <name>", "Display name").option("--phone <phone>", "Primary phone (E.164 format)").option("--email <email>", "Primary email").option("--avatar <url>", "Avatar URL").option("--metadata <json>", "Metadata as JSON string").action(async (id, options) => {
84201
+ const client = getClient();
84202
+ try {
84203
+ const personId = await resolvePersonId(id);
84204
+ const data2 = {};
84205
+ if (options.name !== undefined)
84206
+ data2.displayName = options.name;
84207
+ if (options.phone !== undefined)
84208
+ data2.primaryPhone = options.phone;
84209
+ if (options.email !== undefined)
84210
+ data2.primaryEmail = options.email;
84211
+ if (options.avatar !== undefined)
84212
+ data2.avatarUrl = options.avatar;
84213
+ if (options.metadata !== undefined) {
84214
+ try {
84215
+ data2.metadata = JSON.parse(options.metadata);
84216
+ } catch {
84217
+ error("Invalid JSON for --metadata");
84218
+ }
84219
+ }
84220
+ if (Object.keys(data2).length === 0) {
84221
+ error("No fields to update. Use --name, --phone, --email, --avatar, or --metadata.");
84222
+ }
84223
+ const person = await client.persons.update(personId, data2);
84224
+ success("Person updated");
84225
+ data(person);
84226
+ } catch (err) {
84227
+ const message = err instanceof Error ? err.message : "Unknown error";
84228
+ error(`Failed to update person: ${message}`);
84229
+ }
84230
+ });
84231
+ persons.command("merge <source> <target>").description("Merge source person into target (source is deleted)").option("--reason <reason>", "Reason for merge").action(async (source, target, options) => {
84232
+ const client = getClient();
84233
+ try {
84234
+ const sourceId = await resolvePersonId(source);
84235
+ const targetId = await resolvePersonId(target);
84236
+ const result = await client.persons.merge(sourceId, targetId, options.reason);
84237
+ success(`Merged person ${result.deletedPersonId.slice(0, 8)} into ${result.person.id.slice(0, 8)} (${result.mergedIdentityIds.length} identities moved)`);
84238
+ data(result.person);
84239
+ } catch (err) {
84240
+ const message = err instanceof Error ? err.message : "Unknown error";
84241
+ error(`Failed to merge persons: ${message}`);
84242
+ }
84243
+ });
84244
+ persons.command("link <identityA> <identityB>").description("Link two platform identities to the same person").action(async (identityA, identityB) => {
84245
+ const client = getClient();
84246
+ try {
84247
+ const person = await client.persons.link(identityA, identityB);
84248
+ success(`Identities linked under person ${person.id.slice(0, 8)}`);
84249
+ data(person);
84250
+ } catch (err) {
84251
+ const message = err instanceof Error ? err.message : "Unknown error";
84252
+ error(`Failed to link identities: ${message}`);
84253
+ }
84254
+ });
84255
+ persons.command("unlink <identityId>").description("Unlink a platform identity from its person").option("--reason <reason>", "Reason for unlinking", "Manual unlink").action(async (identityId, options) => {
84256
+ const client = getClient();
84257
+ try {
84258
+ const result = await client.persons.unlink(identityId, options.reason);
84259
+ success(`Identity unlinked, new person ${result.person.id.slice(0, 8)} created`);
84260
+ data(result);
84261
+ } catch (err) {
84262
+ const message = err instanceof Error ? err.message : "Unknown error";
84263
+ error(`Failed to unlink identity: ${message}`);
84264
+ }
84265
+ });
83347
84266
  return persons;
83348
84267
  }
83349
84268
 
83350
84269
  // src/commands/prompts.ts
84270
+ init_output();
83351
84271
  var PROMPT_MAP = {
83352
84272
  image: "prompt.image_description",
83353
84273
  video: "prompt.video_description",
@@ -91457,7 +92377,7 @@ var log15 = createLogger("provider:a2a");
91457
92377
  var import_nats4 = __toESM(require_mod4(), 1);
91458
92378
  import { mkdir, writeFile } from "fs/promises";
91459
92379
  import { homedir as homedir3 } from "os";
91460
- import { join as join5 } from "path";
92380
+ import { join as join6 } from "path";
91461
92381
  var log16 = createLogger("provider:nats-genie");
91462
92382
 
91463
92383
  class NatsGenieProvider {
@@ -91465,7 +92385,7 @@ class NatsGenieProvider {
91465
92385
  name;
91466
92386
  config;
91467
92387
  schema = "nats-genie";
91468
- mode = "fire-and-forget";
92388
+ mode;
91469
92389
  nc = null;
91470
92390
  sc = import_nats4.StringCodec();
91471
92391
  replySubscription = null;
@@ -91473,6 +92393,7 @@ class NatsGenieProvider {
91473
92393
  this.id = id;
91474
92394
  this.name = name;
91475
92395
  this.config = config2;
92396
+ this.mode = config2.mode ?? "fire-and-forget";
91476
92397
  }
91477
92398
  canHandle(_trigger) {
91478
92399
  return true;
@@ -91497,7 +92418,8 @@ class NatsGenieProvider {
91497
92418
  timestamp: new Date().toISOString(),
91498
92419
  traceId: context.traceId,
91499
92420
  messageId: context.source.messageId,
91500
- files: context.content.files
92421
+ files: context.content.files,
92422
+ env: context.env
91501
92423
  };
91502
92424
  try {
91503
92425
  await this.ensureConnected();
@@ -91610,10 +92532,10 @@ class NatsGenieProvider {
91610
92532
  }
91611
92533
  async writeDeadLetter(payload, error2) {
91612
92534
  try {
91613
- const dlDir = join5(homedir3(), ".omni", "dead-letters");
92535
+ const dlDir = join6(homedir3(), ".omni", "dead-letters");
91614
92536
  await mkdir(dlDir, { recursive: true });
91615
92537
  const filename = `nats-genie-${Date.now()}-${payload.chatId}.json`;
91616
- await writeFile(join5(dlDir, filename), JSON.stringify({
92538
+ await writeFile(join6(dlDir, filename), JSON.stringify({
91617
92539
  payload,
91618
92540
  error: error2 instanceof Error ? error2.message : String(error2),
91619
92541
  timestamp: new Date().toISOString()
@@ -91955,14 +92877,18 @@ class HookRegistry {
91955
92877
  }
91956
92878
  // ../core/src/hooks/executor.ts
91957
92879
  var log17 = createLogger("hooks:executor");
92880
+ // src/commands/providers.ts
92881
+ init_output();
92882
+
91958
92883
  // src/commands/providers-setup.ts
91959
92884
  import { execFileSync as execFileSync2, execSync } from "child_process";
91960
92885
  import * as nodeCrypto2 from "crypto";
91961
- import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
92886
+ import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "fs";
91962
92887
  import { homedir as homedir4 } from "os";
91963
- import { dirname as dirname4, resolve as resolve2 } from "path";
92888
+ import { dirname as dirname5, resolve as resolve2 } from "path";
91964
92889
  import { createInterface as createInterface3 } from "readline";
91965
92890
  init_config();
92891
+ init_output();
91966
92892
  async function promptLine2(question, defaultValue = "") {
91967
92893
  const rl = createInterface3({
91968
92894
  input: process.stdin,
@@ -92188,16 +93114,16 @@ async function pairDevice(gatewayUrl, gatewayToken, keypair, spinner) {
92188
93114
  var OPENCLAW_CONFIG_PATH = resolve2(homedir4(), ".openclaw", "openclaw.json");
92189
93115
  var PLUGIN_MARKER = "plugin-openclaw/omni.ts";
92190
93116
  function readOpenClawConfig(configPath) {
92191
- if (!existsSync5(configPath))
93117
+ if (!existsSync6(configPath))
92192
93118
  return {};
92193
- const raw2 = readFileSync3(configPath, "utf-8").trim();
93119
+ const raw2 = readFileSync4(configPath, "utf-8").trim();
92194
93120
  if (!raw2)
92195
93121
  return {};
92196
93122
  return JSON.parse(raw2);
92197
93123
  }
92198
93124
  function writeOpenClawConfig(configPath, config2) {
92199
- mkdirSync4(dirname4(configPath), { recursive: true, mode: 448 });
92200
- writeFileSync3(configPath, `${JSON.stringify(config2, null, 2)}
93125
+ mkdirSync4(dirname5(configPath), { recursive: true, mode: 448 });
93126
+ writeFileSync5(configPath, `${JSON.stringify(config2, null, 2)}
92201
93127
  `, { mode: 384 });
92202
93128
  }
92203
93129
  function isPluginRegistered(config2, marker, pluginPath) {
@@ -92229,10 +93155,10 @@ function isValidUuid(value) {
92229
93155
  }
92230
93156
  function resolvePluginPath(explicit) {
92231
93157
  if (explicit) {
92232
- return existsSync5(explicit) ? resolve2(explicit) : null;
93158
+ return existsSync6(explicit) ? resolve2(explicit) : null;
92233
93159
  }
92234
93160
  const cwdCandidate = resolve2(process.cwd(), "packages/plugin-openclaw/omni.ts");
92235
- return existsSync5(cwdCandidate) ? cwdCandidate : null;
93161
+ return existsSync6(cwdCandidate) ? cwdCandidate : null;
92236
93162
  }
92237
93163
  function registerPlugin(config2, pluginPath, configPath) {
92238
93164
  if (hasOpenClawCli()) {
@@ -92743,10 +93669,47 @@ function createProvidersCommand() {
92743
93669
  return providers2;
92744
93670
  }
92745
93671
 
93672
+ // src/commands/react.ts
93673
+ init_output();
93674
+ function createReactCommand() {
93675
+ return new Command("react").description("React to a message with an emoji").argument("<emoji>", "Emoji to react with").option("--message <id>", "Message ID to react to (default: trigger message from context)").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").action(async (emoji, options) => {
93676
+ const client = getClient();
93677
+ const ctx = await resolveContext({
93678
+ instance: options.instance,
93679
+ chat: options.chat,
93680
+ message: options.message
93681
+ });
93682
+ if (!ctx.instanceId) {
93683
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, or run: omni use <instance>");
93684
+ }
93685
+ if (!ctx.chatId) {
93686
+ return error("No chat in context. Set OMNI_CHAT, use --chat, or run: omni open <contact>");
93687
+ }
93688
+ const messageId = await resolveReplyTo(options.message);
93689
+ if (!messageId) {
93690
+ return error("No message to react to. Set OMNI_MESSAGE, use --message <id>, or ensure context has a trigger message.");
93691
+ }
93692
+ try {
93693
+ const result = await client.messages.sendReaction({
93694
+ instanceId: ctx.instanceId,
93695
+ to: ctx.chatId,
93696
+ messageId,
93697
+ emoji
93698
+ });
93699
+ success(`Reacted ${emoji}`, result);
93700
+ } catch (err) {
93701
+ const message2 = err instanceof Error ? err.message : "Unknown error";
93702
+ error(`Failed to react: ${message2}`);
93703
+ }
93704
+ });
93705
+ }
93706
+
92746
93707
  // src/commands/replay.ts
92747
93708
  init_config();
92748
93709
 
92749
93710
  // src/help.ts
93711
+ init_source();
93712
+ init_output();
92750
93713
  function c2() {
92751
93714
  if (areColorsEnabled()) {
92752
93715
  return source_default;
@@ -92792,6 +93755,7 @@ ${cmdLines.join(`
92792
93755
  }
92793
93756
 
92794
93757
  // src/commands/replay.ts
93758
+ init_output();
92795
93759
  var options = [
92796
93760
  {
92797
93761
  flags: "-s, --since <timestamp>",
@@ -92880,8 +93844,9 @@ ${formatExamples(examples)}`);
92880
93844
  }
92881
93845
 
92882
93846
  // src/commands/restart.ts
92883
- import { join as join6 } from "path";
93847
+ import { join as join7 } from "path";
92884
93848
  init_config();
93849
+ init_output();
92885
93850
  var RESTART_HEALTH_TIMEOUT_MS = 1e4;
92886
93851
  function buildApiRuntimeEnv2() {
92887
93852
  const serverConfig = loadServerConfig();
@@ -92890,9 +93855,9 @@ function buildApiRuntimeEnv2() {
92890
93855
  API_PORT: String(serverConfig.port),
92891
93856
  DATABASE_URL: serverConfig.databaseUrl,
92892
93857
  OMNI_API_KEY: config2.apiKey ?? "",
92893
- MEDIA_STORAGE_PATH: join6(serverConfig.dataDir, "media"),
93858
+ MEDIA_STORAGE_PATH: join7(serverConfig.dataDir, "media"),
92894
93859
  PGSERVE_EMBEDDED: "true",
92895
- PGSERVE_DATA: join6(serverConfig.dataDir, "pgserve"),
93860
+ PGSERVE_DATA: join7(serverConfig.dataDir, "pgserve"),
92896
93861
  NATS_URL: "nats://localhost:4222",
92897
93862
  NODE_ENV: serverConfig.nodeEnv,
92898
93863
  LOG_LEVEL: serverConfig.logLevel
@@ -92925,6 +93890,7 @@ function createRestartCommand() {
92925
93890
 
92926
93891
  // src/commands/resync.ts
92927
93892
  init_config();
93893
+ init_output();
92928
93894
  var options2 = [
92929
93895
  { flags: "-i, --instance <id>", description: "Instance ID or name to resync" },
92930
93896
  { flags: "-a, --all", description: "Resync all connected instances" },
@@ -93032,12 +93998,172 @@ ${formatExamples(examples2)}`);
93032
93998
  return cmd;
93033
93999
  }
93034
94000
 
94001
+ // src/commands/say.ts
94002
+ init_output();
94003
+ function createSayCommand() {
94004
+ return new Command("say").description("Send a text message to the open chat").argument("<text>", "Text message to send").option("--reply [message-id]", "Quote-reply to trigger message or specific message ID").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").action(async (text, options3) => {
94005
+ const client = getClient();
94006
+ const ctx = await resolveContext({
94007
+ instance: options3.instance,
94008
+ chat: options3.chat
94009
+ });
94010
+ if (!ctx.instanceId) {
94011
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, or run: omni use <instance>");
94012
+ }
94013
+ if (!ctx.chatId) {
94014
+ return error("No chat in context. Set OMNI_CHAT, use --chat, or run: omni open <contact>");
94015
+ }
94016
+ let replyTo;
94017
+ if (options3.reply !== undefined) {
94018
+ const replyId = typeof options3.reply === "string" ? options3.reply : undefined;
94019
+ const resolved = await resolveReplyTo(replyId);
94020
+ if (!resolved) {
94021
+ return error("No message to reply to. Set OMNI_MESSAGE, use --reply <id>, or run: omni open <contact>");
94022
+ }
94023
+ replyTo = resolved;
94024
+ }
94025
+ try {
94026
+ const result = await client.messages.send({
94027
+ instanceId: ctx.instanceId,
94028
+ to: ctx.chatId,
94029
+ text,
94030
+ replyTo
94031
+ });
94032
+ success("Message sent", result);
94033
+ } catch (err) {
94034
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94035
+ error(`Failed to send: ${message2}`);
94036
+ }
94037
+ });
94038
+ }
94039
+
94040
+ // src/commands/see.ts
94041
+ import { existsSync as existsSync7, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
94042
+ import { extname as extname4 } from "path";
94043
+ init_output();
94044
+ var MIME_BY_EXT = {
94045
+ ".jpg": "image/jpeg",
94046
+ ".jpeg": "image/jpeg",
94047
+ ".png": "image/png",
94048
+ ".gif": "image/gif",
94049
+ ".webp": "image/webp",
94050
+ ".bmp": "image/bmp",
94051
+ ".heic": "image/heic",
94052
+ ".heif": "image/heif",
94053
+ ".mp4": "video/mp4",
94054
+ ".mov": "video/quicktime",
94055
+ ".webm": "video/webm",
94056
+ ".avi": "video/x-msvideo",
94057
+ ".mkv": "video/x-matroska"
94058
+ };
94059
+ function guessMimeType(path) {
94060
+ const ext = extname4(path).toLowerCase();
94061
+ return MIME_BY_EXT[ext] ?? "application/octet-stream";
94062
+ }
94063
+ function parseMaxTokens(value) {
94064
+ if (value === undefined)
94065
+ return;
94066
+ const n2 = Number.parseInt(value, 10);
94067
+ if (!Number.isFinite(n2) || n2 <= 0 || n2 > 8192) {
94068
+ error(`Invalid --max-tokens "${value}". Must be a positive integer up to 8192.`);
94069
+ }
94070
+ return n2;
94071
+ }
94072
+ function loadMedia(file) {
94073
+ if (!existsSync7(file)) {
94074
+ error(`File not found: ${file}`);
94075
+ }
94076
+ const stat = statSync2(file);
94077
+ if (!stat.isFile()) {
94078
+ error(`Not a regular file: ${file}`);
94079
+ }
94080
+ if (stat.size === 0) {
94081
+ error(`File is empty: ${file}`);
94082
+ }
94083
+ try {
94084
+ return { buffer: readFileSync5(file), mimeType: guessMimeType(file) };
94085
+ } catch (err) {
94086
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94087
+ return error(`Failed to read ${file}: ${message2}`);
94088
+ }
94089
+ }
94090
+ async function describeMedia(client, buffer2, mimeType, prompt, options3, maxTokens) {
94091
+ try {
94092
+ const result = await client.media.vision({
94093
+ media: buffer2,
94094
+ mimeType,
94095
+ provider: options3.provider,
94096
+ prompt,
94097
+ language: options3.language,
94098
+ maxTokens
94099
+ });
94100
+ return { text: result.text, provider: result.provider, processingMs: result.processingMs };
94101
+ } catch (err) {
94102
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94103
+ return error(`Vision description failed: ${message2}`);
94104
+ }
94105
+ }
94106
+ async function sendAsReply(client, description, options3) {
94107
+ const ctx = await resolveContext({ instance: options3.instance, chat: options3.chat });
94108
+ if (!ctx.instanceId) {
94109
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, or run: omni use <instance>");
94110
+ }
94111
+ if (!ctx.chatId) {
94112
+ return error("No chat in context. Set OMNI_CHAT, use --chat, or run: omni open <contact>");
94113
+ }
94114
+ const replyId = typeof options3.reply === "string" ? options3.reply : undefined;
94115
+ const replyTo = await resolveReplyTo(replyId);
94116
+ if (!replyTo) {
94117
+ return error("No message to reply to. Set OMNI_MESSAGE, use --reply <id>, or run: omni open <contact>");
94118
+ }
94119
+ try {
94120
+ const sent = await client.messages.send({
94121
+ instanceId: ctx.instanceId,
94122
+ to: ctx.chatId,
94123
+ text: description.text,
94124
+ replyTo
94125
+ });
94126
+ success("Description sent as reply", {
94127
+ provider: description.provider,
94128
+ processingMs: description.processingMs,
94129
+ text: description.text,
94130
+ ...sent
94131
+ });
94132
+ } catch (err) {
94133
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94134
+ error(`Failed to send reply: ${message2}`);
94135
+ }
94136
+ }
94137
+ function printDescription(description) {
94138
+ if (getCurrentFormat() === "json") {
94139
+ data({ provider: description.provider, processingMs: description.processingMs, text: description.text });
94140
+ } else {
94141
+ raw(description.text);
94142
+ }
94143
+ }
94144
+ function createSeeCommand() {
94145
+ return new Command("see").description("Describe an image or video (prints to stdout); optionally quote-reply").argument("<file>", "Path to image or video file").argument("[prompt]", 'Guided prompt (e.g. "what color is the cat?")').option("--provider <name>", "Vision provider (gemini). Default: server config.").option("--language <code>", "Response language (e.g. en, pt-BR)").option("--max-tokens <n>", "Maximum output tokens (1-8192)").option("--reply [message-id]", "Quote-reply trigger (or specific message ID) with the description").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").action(async (file, prompt, options3) => {
94146
+ const { buffer: buffer2, mimeType } = loadMedia(file);
94147
+ const maxTokens = parseMaxTokens(options3.maxTokens);
94148
+ const client = getClient();
94149
+ const description = await describeMedia(client, buffer2, mimeType, prompt, options3, maxTokens);
94150
+ if (options3.reply !== undefined) {
94151
+ await sendAsReply(client, description, options3);
94152
+ return;
94153
+ }
94154
+ printDescription(description);
94155
+ });
94156
+ }
94157
+
93035
94158
  // src/commands/send.ts
93036
- import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
93037
- import { basename as basename2, extname } from "path";
94159
+ import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
94160
+ import { basename as basename5, extname as extname5 } from "path";
94161
+ init_source();
93038
94162
  init_config();
93039
- function getMediaType(path) {
93040
- const ext = extname(path).toLowerCase();
94163
+ init_output();
94164
+ init_output();
94165
+ function getMediaType2(path) {
94166
+ const ext = extname5(path).toLowerCase();
93041
94167
  const imageExts = [".jpg", ".jpeg", ".png", ".gif", ".webp"];
93042
94168
  const audioExts = [".mp3", ".wav", ".ogg", ".m4a", ".opus"];
93043
94169
  const videoExts = [".mp4", ".webm", ".mov", ".avi"];
@@ -93050,7 +94176,7 @@ function getMediaType(path) {
93050
94176
  return "document";
93051
94177
  }
93052
94178
  function readFileAsBase64(path) {
93053
- const buffer2 = readFileSync4(path);
94179
+ const buffer2 = readFileSync6(path);
93054
94180
  return buffer2.toString("base64");
93055
94181
  }
93056
94182
  var messageSenders = {
@@ -93071,13 +94197,13 @@ var messageSenders = {
93071
94197
  const { to, media } = options3;
93072
94198
  if (!to || !media)
93073
94199
  return;
93074
- if (!existsSync6(media)) {
94200
+ if (!existsSync8(media)) {
93075
94201
  error(`File not found: ${media}`);
93076
94202
  return;
93077
94203
  }
93078
- const mediaType = getMediaType(media);
94204
+ const mediaType = getMediaType2(media);
93079
94205
  const base64 = readFileAsBase64(media);
93080
- const filename = basename2(media);
94206
+ const filename = basename5(media);
93081
94207
  const result = await client.messages.sendMedia({
93082
94208
  instanceId,
93083
94209
  to,
@@ -93402,7 +94528,21 @@ function createSendCommand() {
93402
94528
  send.configureHelp({
93403
94529
  formatHelp: () => buildGroupedSendHelp()
93404
94530
  });
93405
- send.description("Send a message to a recipient").option("--instance <id>", "Instance ID (uses default if not specified)").option("--to <recipient>", "Recipient: WA JID, phone number, or Omni chat/person UUID").option("--text <text>", "Send text message").option("--reply-to <id>", "Reply to a message ID").option("--thread-id <id>", "Thread/topic ID (Telegram forum topic, etc.)").option("--media <path>", "Send media file (image, audio, video, document)").option("--caption <text>", "Caption for media").option("--voice", "Send audio as voice note").option("--reaction <emoji>", "Send reaction emoji").option("--message <id>", "Message ID to react to").option("--sticker <url>", "Send sticker (URL or base64)").option("--contact", "Send contact card").option("--name <name>", "Contact name").option("--phone <phone>", "Contact phone number").option("--email <email>", "Contact email").option("--location", "Send location").option("--lat <latitude>", "Latitude", Number.parseFloat).option("--lng <longitude>", "Longitude", Number.parseFloat).option("--address <address>", "Location address").option("--poll <question>", "Send poll with question").option("--options <answers>", "Poll options (comma-separated)").option("--multi-select", "Allow multiple selections").option("--duration <hours>", "Poll duration in hours", Number.parseInt).option("--embed", "Send embed message").option("--title <title>", "Embed title").option("--description <desc>", "Embed description").option("--color <color>", "Embed color (hex)", Number.parseInt).option("--url <url>", "Embed URL").option("--presence <type>", "Send presence indicator (typing, recording, paused)").option("--tts <text>", "Send TTS voice note (text-to-speech)").option("--voice-id <id>", "ElevenLabs voice ID for TTS").option("--presence-delay <ms>", "Recording presence duration in ms", Number.parseInt).option("--forward", "Forward a message to another chat").option("--from-chat <chatId>", "Source chat ID for forwarding").action(async (options3) => {
94531
+ send.description("Send a message to a recipient").argument("[file]", "File to send as media (shorthand for --media, uses context for instance/chat)").option("--instance <id>", "Instance ID (uses default if not specified)").option("--to <recipient>", "Recipient: WA JID, phone number, or Omni chat/person UUID").option("--text <text>", "Send text message").option("--reply-to <id>", "Reply to a message ID").option("--thread-id <id>", "Thread/topic ID (Telegram forum topic, etc.)").option("--media <path>", "Send media file (image, audio, video, document)").option("--caption <text>", "Caption for media").option("--voice", "Send audio as voice note").option("--reaction <emoji>", "Send reaction emoji").option("--message <id>", "Message ID to react to").option("--sticker <url>", "Send sticker (URL or base64)").option("--contact", "Send contact card").option("--name <name>", "Contact name").option("--phone <phone>", "Contact phone number").option("--email <email>", "Contact email").option("--location", "Send location").option("--lat <latitude>", "Latitude", Number.parseFloat).option("--lng <longitude>", "Longitude", Number.parseFloat).option("--address <address>", "Location address").option("--poll <question>", "Send poll with question").option("--options <answers>", "Poll options (comma-separated)").option("--multi-select", "Allow multiple selections").option("--duration <hours>", "Poll duration in hours", Number.parseInt).option("--embed", "Send embed message").option("--title <title>", "Embed title").option("--description <desc>", "Embed description").option("--color <color>", "Embed color (hex)", Number.parseInt).option("--url <url>", "Embed URL").option("--presence <type>", "Send presence indicator (typing, recording, paused)").option("--tts <text>", "Send TTS voice note (text-to-speech)").option("--voice-id <id>", "ElevenLabs voice ID for TTS").option("--presence-delay <ms>", "Recording presence duration in ms", Number.parseInt).option("--forward", "Forward a message to another chat").option("--from-chat <chatId>", "Source chat ID for forwarding").action(async (file, options3) => {
94532
+ if (file && !options3.media) {
94533
+ options3.media = file;
94534
+ if (!options3.to) {
94535
+ const ctx = await resolveContext({ instance: options3.instance });
94536
+ if (!ctx.instanceId) {
94537
+ error("No instance in context. Use --instance, set OMNI_INSTANCE, or run: omni use <instance>");
94538
+ }
94539
+ if (!ctx.chatId) {
94540
+ error("No chat in context. Use --to, set OMNI_CHAT, or run: omni open <contact>");
94541
+ }
94542
+ options3.instance = ctx.instanceId;
94543
+ options3.to = ctx.chatId;
94544
+ }
94545
+ }
93406
94546
  const messageType = getMessageType(options3);
93407
94547
  if (!messageType) {
93408
94548
  error("No message type specified. Use --text, --media, --reaction, --forward, etc.");
@@ -93420,6 +94560,7 @@ function createSendCommand() {
93420
94560
  }
93421
94561
 
93422
94562
  // src/commands/settings.ts
94563
+ init_output();
93423
94564
  function createSettingsCommand() {
93424
94565
  const settings = new Command("settings").description("Manage API settings");
93425
94566
  settings.command("list").description("List all settings").option("--category <category>", "Filter by category").action(async (options3) => {
@@ -93477,11 +94618,122 @@ function createSettingsCommand() {
93477
94618
  return settings;
93478
94619
  }
93479
94620
 
94621
+ // src/commands/speak.ts
94622
+ import { writeFile as writeFile2 } from "fs/promises";
94623
+ init_output();
94624
+ var ALLOWED_FORMATS2 = ["mp3", "ogg", "opus", "wav", "pcm", "flac", "aac"];
94625
+ function parseFormat2(value) {
94626
+ if (!value)
94627
+ return;
94628
+ const normalized = value.toLowerCase();
94629
+ if (!ALLOWED_FORMATS2.includes(normalized)) {
94630
+ error(`Invalid --format "${value}". Allowed: ${ALLOWED_FORMATS2.join(", ")}`);
94631
+ }
94632
+ return normalized;
94633
+ }
94634
+ function parseSpeed(value) {
94635
+ if (value === undefined)
94636
+ return;
94637
+ const n2 = Number.parseFloat(value);
94638
+ if (Number.isNaN(n2) || n2 < 0.5 || n2 > 2) {
94639
+ error(`Invalid --speed "${value}". Must be a number between 0.5 and 2.0.`);
94640
+ }
94641
+ return n2;
94642
+ }
94643
+ function createSpeakCommand() {
94644
+ return new Command("speak").description("Synthesize text to speech and send as a voice note (or save with --output)").argument("<text>", "Text to convert to speech").option("--provider <name>", "TTS provider (gemini, elevenlabs). Default: server config.").option("--voice <name>", "Voice identifier (e.g. Kore for Gemini, JBFqn... for ElevenLabs)").option("--style <prompt>", 'Style prompt prepended to text (Gemini only, e.g. "Say cheerfully")').option("--language <code>", "BCP-47 language code (e.g. en-US, pt-BR)").option("--speed <factor>", "Speaking speed multiplier 0.5-2.0 (provider-dependent)").option("--format <fmt>", `Audio format: ${ALLOWED_FORMATS2.join(", ")} (default: ogg)`).option("--output <path>", "Save audio to file instead of sending").option("--instance <id>", "Override instance (default: from context)").option("--chat <id>", "Override chat (default: from context)").action(async (text, options3) => {
94645
+ const client = getClient();
94646
+ const format = parseFormat2(options3.format);
94647
+ const speed = parseSpeed(options3.speed);
94648
+ let audioBuffer;
94649
+ let mimeType;
94650
+ let durationMs;
94651
+ let providerName;
94652
+ try {
94653
+ const result = await client.media.tts({
94654
+ text,
94655
+ provider: options3.provider,
94656
+ voice: options3.voice,
94657
+ language: options3.language,
94658
+ speed,
94659
+ format,
94660
+ style: options3.style
94661
+ });
94662
+ audioBuffer = result.audio;
94663
+ mimeType = result.mimeType;
94664
+ durationMs = result.durationMs;
94665
+ providerName = result.provider;
94666
+ } catch (err) {
94667
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94668
+ return error(`TTS synthesis failed: ${message2}`);
94669
+ }
94670
+ if (options3.output) {
94671
+ try {
94672
+ await writeFile2(options3.output, audioBuffer);
94673
+ return success("Audio saved", {
94674
+ path: options3.output,
94675
+ provider: providerName,
94676
+ mimeType,
94677
+ durationMs,
94678
+ sizeKb: Math.round(audioBuffer.length / 1024 * 100) / 100
94679
+ });
94680
+ } catch (err) {
94681
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94682
+ return error(`Failed to write ${options3.output}: ${message2}`);
94683
+ }
94684
+ }
94685
+ const ctx = await resolveContext({
94686
+ instance: options3.instance,
94687
+ chat: options3.chat
94688
+ });
94689
+ if (!ctx.instanceId) {
94690
+ return error("No instance in context. Set OMNI_INSTANCE, use --instance, run: omni use <instance>, or pass --output to save.");
94691
+ }
94692
+ if (!ctx.chatId) {
94693
+ return error("No chat in context. Set OMNI_CHAT, use --chat, run: omni open <contact>, or pass --output to save.");
94694
+ }
94695
+ try {
94696
+ const result = await client.messages.sendMedia({
94697
+ instanceId: ctx.instanceId,
94698
+ to: ctx.chatId,
94699
+ type: "audio",
94700
+ base64: audioBuffer.toString("base64"),
94701
+ filename: pickFilename(mimeType, providerName),
94702
+ voiceNote: true
94703
+ });
94704
+ success("Voice note sent", {
94705
+ provider: providerName,
94706
+ durationMs,
94707
+ sizeKb: Math.round(audioBuffer.length / 1024 * 100) / 100,
94708
+ ...result
94709
+ });
94710
+ } catch (err) {
94711
+ const message2 = err instanceof Error ? err.message : "Unknown error";
94712
+ error(`Failed to send voice note: ${message2}`);
94713
+ }
94714
+ });
94715
+ }
94716
+ function pickFilename(mimeType, provider) {
94717
+ const lower = mimeType.toLowerCase();
94718
+ if (lower.includes("ogg") || lower.includes("opus"))
94719
+ return `${provider}-speak.ogg`;
94720
+ if (lower.includes("wav"))
94721
+ return `${provider}-speak.wav`;
94722
+ if (lower.includes("mp3") || lower.includes("mpeg"))
94723
+ return `${provider}-speak.mp3`;
94724
+ if (lower.includes("flac"))
94725
+ return `${provider}-speak.flac`;
94726
+ if (lower.includes("aac") || lower.includes("m4a"))
94727
+ return `${provider}-speak.m4a`;
94728
+ return `${provider}-speak.bin`;
94729
+ }
94730
+
93480
94731
  // src/commands/start.ts
93481
- import { existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
94732
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5 } from "fs";
93482
94733
  import { homedir as homedir5 } from "os";
93483
- import { join as join7 } from "path";
94734
+ import { join as join8 } from "path";
93484
94735
  init_config();
94736
+ init_output();
93485
94737
  var START_HEALTH_TIMEOUT_MS = 1e4;
93486
94738
  function buildApiRuntimeEnv3() {
93487
94739
  const serverConfig = loadServerConfig();
@@ -93490,10 +94742,10 @@ function buildApiRuntimeEnv3() {
93490
94742
  API_PORT: String(serverConfig.port),
93491
94743
  DATABASE_URL: serverConfig.databaseUrl,
93492
94744
  OMNI_API_KEY: config2.apiKey ?? "",
93493
- MEDIA_STORAGE_PATH: join7(serverConfig.dataDir, "media"),
93494
- OMNI_PACKAGES_DIR: join7(serverConfig.dataDir, "packages"),
94745
+ MEDIA_STORAGE_PATH: join8(serverConfig.dataDir, "media"),
94746
+ OMNI_PACKAGES_DIR: join8(serverConfig.dataDir, "packages"),
93495
94747
  PGSERVE_EMBEDDED: "true",
93496
- PGSERVE_DATA: join7(serverConfig.dataDir, "pgserve"),
94748
+ PGSERVE_DATA: join8(serverConfig.dataDir, "pgserve"),
93497
94749
  NATS_URL: "nats://localhost:4222",
93498
94750
  NODE_ENV: serverConfig.nodeEnv,
93499
94751
  LOG_LEVEL: serverConfig.logLevel
@@ -93504,7 +94756,7 @@ async function runStart() {
93504
94756
  pm2NotFoundError();
93505
94757
  }
93506
94758
  const bundlePath = getServerBundlePath();
93507
- if (!existsSync7(bundlePath)) {
94759
+ if (!existsSync9(bundlePath)) {
93508
94760
  bundleNotFoundError(bundlePath);
93509
94761
  }
93510
94762
  const serverConfig = loadServerConfig();
@@ -93517,10 +94769,10 @@ async function runStart() {
93517
94769
  error(`Failed to start ${PM2_PROCESSES.api} (pm2 exit code ${apiCode})`, undefined, 1);
93518
94770
  return;
93519
94771
  }
93520
- const natsPath = join7(homedir5(), ".omni", "nats-server");
93521
- if (existsSync7(natsPath)) {
94772
+ const natsPath = join8(homedir5(), ".omni", "nats-server");
94773
+ if (existsSync9(natsPath)) {
93522
94774
  info(`Starting ${PM2_PROCESSES.nats}...`);
93523
- const natsDataDir = join7(serverConfig.dataDir, "nats");
94775
+ const natsDataDir = join8(serverConfig.dataDir, "nats");
93524
94776
  mkdirSync5(natsDataDir, { recursive: true });
93525
94777
  const natsCode = await runPm2(["start", natsPath, "--name", PM2_PROCESSES.nats, "--", "-js", "-sd", natsDataDir]);
93526
94778
  if (natsCode !== 0) {
@@ -93544,6 +94796,7 @@ function createStartCommand() {
93544
94796
 
93545
94797
  // src/commands/status.ts
93546
94798
  init_config();
94799
+ init_output();
93547
94800
  function formatUptime(ms) {
93548
94801
  if (ms === undefined || ms === 0)
93549
94802
  return "-";
@@ -93668,6 +94921,7 @@ function createStatusCommand() {
93668
94921
  }
93669
94922
 
93670
94923
  // src/commands/stop.ts
94924
+ init_output();
93671
94925
  var LEGACY_PROCESSES = ["omni-v2-api", "omni-v2-nats"];
93672
94926
  async function runStop() {
93673
94927
  if (!await isPm2Available()) {
@@ -93687,6 +94941,7 @@ function createStopCommand() {
93687
94941
  }
93688
94942
 
93689
94943
  // src/commands/tts.ts
94944
+ init_output();
93690
94945
  function createTtsCommand() {
93691
94946
  const tts = new Command("tts").description("Text-to-speech operations");
93692
94947
  tts.command("voices").description("List available TTS voices").action(async () => {
@@ -93714,6 +94969,7 @@ function createTtsCommand() {
93714
94969
  // src/commands/update.ts
93715
94970
  import { createInterface as createInterface4 } from "readline";
93716
94971
  init_config();
94972
+ init_output();
93717
94973
  var PACKAGE_NAME = "@automagik/omni";
93718
94974
  var UPDATE_HEALTH_TIMEOUT_MS = 1e4;
93719
94975
  async function fetchLatestVersion() {
@@ -93863,7 +95119,29 @@ Behavior:
93863
95119
  `).action(runUpdate);
93864
95120
  }
93865
95121
 
95122
+ // src/commands/use.ts
95123
+ init_output();
95124
+ function createUseCommand() {
95125
+ return new Command("use").description("Set active instance for verb commands").argument("<instance>", "Instance name, ID, or prefix").action(async (instance2) => {
95126
+ const client = getClient();
95127
+ const instanceId = await resolveInstanceId(instance2);
95128
+ try {
95129
+ await client.context.use(instanceId);
95130
+ } catch (err) {
95131
+ const message2 = err instanceof Error ? err.message : "Unknown error";
95132
+ return error(`Failed to set active instance: ${message2}`);
95133
+ }
95134
+ try {
95135
+ const inst = await client.instances.get(instanceId);
95136
+ success(`Active instance: ${inst.name} (${instanceId.slice(0, 8)}\u2026)`);
95137
+ } catch {
95138
+ success(`Active instance: ${instanceId.slice(0, 8)}\u2026`);
95139
+ }
95140
+ });
95141
+ }
95142
+
93866
95143
  // src/commands/webhooks.ts
95144
+ init_output();
93867
95145
  function createWebhooksCommand() {
93868
95146
  const webhooks = new Command("webhooks").description("Manage webhook sources");
93869
95147
  webhooks.command("list").description("List webhook sources").option("--enabled", "Show only enabled sources").option("--disabled", "Show only disabled sources").action(async (options3) => {
@@ -93987,11 +95265,38 @@ function createWebhooksCommand() {
93987
95265
  return webhooks;
93988
95266
  }
93989
95267
 
95268
+ // src/commands/where.ts
95269
+ init_output();
95270
+ function createWhereCommand() {
95271
+ return new Command("where").description("Show current conversation context (instance, chat, message)").action(async () => {
95272
+ const ctx = await resolveContext();
95273
+ if (ctx.source === "none") {
95274
+ warn("No active context. Run: omni open <contact> or omni use <instance>");
95275
+ return;
95276
+ }
95277
+ const sourceLabel = {
95278
+ flags: "CLI flags",
95279
+ env: "environment variables",
95280
+ api: "stored context (PG)",
95281
+ config: "config defaults"
95282
+ };
95283
+ data({
95284
+ instance: ctx.instanceId ?? "(not set)",
95285
+ chat: ctx.chatId ?? "(not set)",
95286
+ message: ctx.messageId ?? "(not set)",
95287
+ source: sourceLabel[ctx.source] ?? ctx.source
95288
+ });
95289
+ });
95290
+ }
95291
+
93990
95292
  // src/index.ts
93991
95293
  init_config();
95294
+ init_output();
93992
95295
 
93993
95296
  // src/status.ts
95297
+ init_source();
93994
95298
  init_config();
95299
+ init_output();
93995
95300
  function c4() {
93996
95301
  if (areColorsEnabled()) {
93997
95302
  return source_default;
@@ -94158,6 +95463,48 @@ var COMMANDS = [
94158
95463
  helpGroup: "Core",
94159
95464
  helpDescription: "Send message (text, media, location, poll)"
94160
95465
  },
95466
+ {
95467
+ create: createSayCommand,
95468
+ category: "core",
95469
+ helpGroup: "Core",
95470
+ helpDescription: "Send text to open chat (verb command)"
95471
+ },
95472
+ {
95473
+ create: createReactCommand,
95474
+ category: "core",
95475
+ helpGroup: "Core",
95476
+ helpDescription: "React to a message with emoji (verb command)"
95477
+ },
95478
+ {
95479
+ create: createListenCommand,
95480
+ category: "core",
95481
+ helpGroup: "Core",
95482
+ helpDescription: "Transcribe audio to text (verb command)"
95483
+ },
95484
+ {
95485
+ create: createImagineCommand,
95486
+ category: "core",
95487
+ helpGroup: "Core",
95488
+ helpDescription: "Generate an image from a prompt (Gemini Nano Banana, verb command)"
95489
+ },
95490
+ {
95491
+ create: createFilmCommand,
95492
+ category: "core",
95493
+ helpGroup: "Core",
95494
+ helpDescription: "Generate a video from a prompt (Gemini Veo 3.1, verb command)"
95495
+ },
95496
+ {
95497
+ create: createSpeakCommand,
95498
+ category: "core",
95499
+ helpGroup: "Core",
95500
+ helpDescription: "Synthesize text to speech and send as voice note (verb command)"
95501
+ },
95502
+ {
95503
+ create: createSeeCommand,
95504
+ category: "core",
95505
+ helpGroup: "Core",
95506
+ helpDescription: "Describe an image or video via Gemini Vision (verb command)"
95507
+ },
94161
95508
  { create: createChatsCommand, category: "core", helpGroup: "Core", helpDescription: "List and manage conversations" },
94162
95509
  {
94163
95510
  create: createMessagesCommand,
@@ -94171,6 +95518,36 @@ var COMMANDS = [
94171
95518
  helpGroup: "Core",
94172
95519
  helpDescription: "Text-to-speech operations"
94173
95520
  },
95521
+ {
95522
+ create: createOpenCommand,
95523
+ category: "core",
95524
+ helpGroup: "Core",
95525
+ helpDescription: "Open conversation context (set active chat)"
95526
+ },
95527
+ {
95528
+ create: createCloseCommand,
95529
+ category: "core",
95530
+ helpGroup: "Core",
95531
+ helpDescription: "Clear active conversation context"
95532
+ },
95533
+ {
95534
+ create: createUseCommand,
95535
+ category: "core",
95536
+ helpGroup: "Core",
95537
+ helpDescription: "Set active instance for verb commands"
95538
+ },
95539
+ {
95540
+ create: createWhereCommand,
95541
+ category: "core",
95542
+ helpGroup: "Core",
95543
+ helpDescription: "Show current context (instance, chat)"
95544
+ },
95545
+ {
95546
+ create: createDoneCommand,
95547
+ category: "core",
95548
+ helpGroup: "Core",
95549
+ helpDescription: "Close turn (send final message + emit turn.done)"
95550
+ },
94174
95551
  {
94175
95552
  create: createChannelsCommand,
94176
95553
  category: "core",