@automagik/omni 2.260331.1 → 2.260405.1

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 (41) hide show
  1. package/db/drizzle/0013_curious_leo.sql +4 -0
  2. package/db/drizzle/0014_overrated_silver_fox.sql +5 -0
  3. package/db/drizzle/0015_burly_trauma.sql +27 -0
  4. package/db/drizzle/meta/0013_snapshot.json +6754 -0
  5. package/db/drizzle/meta/0014_snapshot.json +6784 -0
  6. package/db/drizzle/meta/0015_snapshot.json +7025 -0
  7. package/db/drizzle/meta/_journal.json +21 -0
  8. package/dist/commands/close.d.ts +11 -0
  9. package/dist/commands/close.d.ts.map +1 -0
  10. package/dist/commands/connect.d.ts +1 -1
  11. package/dist/commands/done.d.ts +14 -0
  12. package/dist/commands/done.d.ts.map +1 -0
  13. package/dist/commands/film.d.ts +16 -0
  14. package/dist/commands/film.d.ts.map +1 -0
  15. package/dist/commands/imagine.d.ts +16 -0
  16. package/dist/commands/imagine.d.ts.map +1 -0
  17. package/dist/commands/instances.d.ts.map +1 -1
  18. package/dist/commands/listen.d.ts +18 -0
  19. package/dist/commands/listen.d.ts.map +1 -0
  20. package/dist/commands/open.d.ts +12 -0
  21. package/dist/commands/open.d.ts.map +1 -0
  22. package/dist/commands/persons.d.ts +4 -0
  23. package/dist/commands/persons.d.ts.map +1 -1
  24. package/dist/commands/react.d.ts +11 -0
  25. package/dist/commands/react.d.ts.map +1 -0
  26. package/dist/commands/say.d.ts +12 -0
  27. package/dist/commands/say.d.ts.map +1 -0
  28. package/dist/commands/see.d.ts +15 -0
  29. package/dist/commands/see.d.ts.map +1 -0
  30. package/dist/commands/send.d.ts.map +1 -1
  31. package/dist/commands/speak.d.ts +18 -0
  32. package/dist/commands/speak.d.ts.map +1 -0
  33. package/dist/commands/use.d.ts +12 -0
  34. package/dist/commands/use.d.ts.map +1 -0
  35. package/dist/commands/where.d.ts +11 -0
  36. package/dist/commands/where.d.ts.map +1 -0
  37. package/dist/context.d.ts +43 -0
  38. package/dist/context.d.ts.map +1 -0
  39. package/dist/index.js +2137 -756
  40. package/dist/server/index.js +30246 -2926
  41. 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.260331.1",
76890
+ version: "2.260405.1",
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({
@@ -79673,7 +79940,7 @@ function createConnectCommand() {
79673
79940
  info(`Discovering agent "${agentName}" from genie directory...`);
79674
79941
  let agentEntry;
79675
79942
  try {
79676
- const stdout = execFileSync("genie", ["dir", "get", agentName, "--json"], {
79943
+ const stdout = execFileSync("genie", ["dir", "ls", agentName, "--json"], {
79677
79944
  encoding: "utf-8",
79678
79945
  env: process.env,
79679
79946
  timeout: 1e4
@@ -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,7 +82090,8 @@ function createInstallCommand() {
81401
82090
 
81402
82091
  // src/commands/instances.ts
81403
82092
  var import_qrcode_terminal = __toESM(require_main(), 1);
81404
- var VALID_CHANNELS2 = ["whatsapp-baileys", "whatsapp-cloud", "discord", "slack", "telegram"];
82093
+ init_output();
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) {
81407
82097
  if (val === "null")
@@ -81474,6 +82164,10 @@ function applyMiscFields(body, opts) {
81474
82164
  setVal(body, "discordBotToken", opts.discordToken);
81475
82165
  setVal(body, "slackBotToken", opts.slackBotToken);
81476
82166
  setVal(body, "slackAppToken", opts.slackAppToken);
82167
+ setVal(body, "gupshupApiKey", opts.gupshupApiKey);
82168
+ setVal(body, "gupshupAppName", opts.gupshupAppName);
82169
+ setVal(body, "gupshupSourcePhone", opts.gupshupSourcePhone);
82170
+ setVal(body, "webhookVerifyToken", opts.gupshupWebhookVerifyToken);
81477
82171
  if (opts.triggerEvents !== undefined) {
81478
82172
  const raw2 = opts.triggerEvents;
81479
82173
  body.triggerEvents = raw2 === "null" ? null : raw2.split(",").map((s) => s.trim());
@@ -81577,7 +82271,7 @@ function createInstancesCommand() {
81577
82271
  error(`Failed to get instance: ${message}`, undefined, 3);
81578
82272
  }
81579
82273
  });
81580
- instances.command("create").description("Create a new instance (supports all API fields)").requiredOption("--name <name>", "Instance name").requiredOption("--channel <type>", `Channel type (${VALID_CHANNELS2.join(", ")})`).option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear)').option("--agent-provider <id>", "Agent provider ID").option("--agent <id>", "Agent ID").option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v) => Number.parseInt(v, 10)).option("--agent-stream-mode", "Enable streaming responses").option("--agent-session-strategy <strategy>", "Session strategy: per_user, per_chat, per_user_per_chat").option("--agent-prefix-sender-name", "Prefix messages with sender name").option("--no-agent-prefix-sender-name", "Disable sender name prefix").option("--agent-wait-for-media", "Wait for media processing before dispatch").option("--no-agent-wait-for-media", "Dispatch immediately without waiting for media").option("--agent-send-media-path", "Include file path in formatted media text").option("--no-agent-send-media-path", "Exclude file path from formatted media text").option("--agent-send-media-path-types <types>", "Content types that receive file path (comma-separated: image,video,document)").option("--reply-filter-mode <mode>", "Reply filter: all or filtered").option("--reply-on-dm", "Reply to DMs").option("--no-reply-on-dm", "Ignore DMs").option("--reply-on-mention", "Reply when @mentioned").option("--no-reply-on-mention", "Ignore @mentions").option("--reply-on-reply", "Reply when message is reply to bot").option("--no-reply-on-reply", "Ignore replies").option("--reply-on-name", "Reply when bot name appears in text").option("--no-reply-on-name", "Ignore name matches").option("--reply-name-patterns <patterns>", "Custom name patterns (comma-separated)").option("--enable-auto-split", "Split responses on double newlines").option("--no-enable-auto-split", "Disable auto-split").option("--message-format-mode <mode>", "Format mode: convert or passthrough").option("--debounce-mode <mode>", "Debounce mode: disabled, fixed, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--debounce-group <ms>", "Group chat debounce in ms", (v) => Number.parseInt(v, 10)).option("--agent-gate", "Enable LLM response gate").option("--agent-gate-model <model>", "Model for response gate").option("--agent-gate-prompt <prompt>", "Custom gate prompt").option("--tts-voice <id>", "ElevenLabs voice ID").option("--tts-model <id>", "ElevenLabs model ID").option("--access-mode <mode>", "Access mode: disabled, blocklist, or allowlist").option("--reaction-ack <mode>", "Reaction ack mode (on|off)").option("--reaction-ack-emoji <json>", "Per-channel emoji map as JSON").option("--ack-timeout <ms>", "Ack timeout in milliseconds", (v) => Number.parseInt(v, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", "Telegram bot token").option("--discord-token <token>", "Discord bot token").option("--slack-bot-token <token>", "Slack bot token").option("--slack-app-token <token>", "Slack app token").option("--is-default", "Set as default instance for channel").action(async (options) => {
82274
+ instances.command("create").description("Create a new instance (supports all API fields)").requiredOption("--name <name>", "Instance name").requiredOption("--channel <type>", `Channel type (${VALID_CHANNELS2.join(", ")})`).option("--agent-fk-id <uuid>", 'Agent FK UUID (references agents table, use "null" to clear)').option("--agent-provider <id>", "Agent provider ID").option("--agent <id>", "Agent ID").option("--agent-type <type>", "Agent type: agent, team, or workflow").option("--agent-timeout <seconds>", "Agent timeout in seconds", (v) => Number.parseInt(v, 10)).option("--agent-stream-mode", "Enable streaming responses").option("--agent-session-strategy <strategy>", "Session strategy: per_user, per_chat, per_user_per_chat").option("--agent-prefix-sender-name", "Prefix messages with sender name").option("--no-agent-prefix-sender-name", "Disable sender name prefix").option("--agent-wait-for-media", "Wait for media processing before dispatch").option("--no-agent-wait-for-media", "Dispatch immediately without waiting for media").option("--agent-send-media-path", "Include file path in formatted media text").option("--no-agent-send-media-path", "Exclude file path from formatted media text").option("--agent-send-media-path-types <types>", "Content types that receive file path (comma-separated: image,video,document)").option("--reply-filter-mode <mode>", "Reply filter: all or filtered").option("--reply-on-dm", "Reply to DMs").option("--no-reply-on-dm", "Ignore DMs").option("--reply-on-mention", "Reply when @mentioned").option("--no-reply-on-mention", "Ignore @mentions").option("--reply-on-reply", "Reply when message is reply to bot").option("--no-reply-on-reply", "Ignore replies").option("--reply-on-name", "Reply when bot name appears in text").option("--no-reply-on-name", "Ignore name matches").option("--reply-name-patterns <patterns>", "Custom name patterns (comma-separated)").option("--enable-auto-split", "Split responses on double newlines").option("--no-enable-auto-split", "Disable auto-split").option("--message-format-mode <mode>", "Format mode: convert or passthrough").option("--debounce-mode <mode>", "Debounce mode: disabled, fixed, or randomized").option("--debounce-min <ms>", "Minimum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-max <ms>", "Maximum debounce delay in ms", (v) => Number.parseInt(v, 10)).option("--debounce-restart-on-typing", "Restart debounce timer on typing").option("--debounce-group <ms>", "Group chat debounce in ms", (v) => Number.parseInt(v, 10)).option("--agent-gate", "Enable LLM response gate").option("--agent-gate-model <model>", "Model for response gate").option("--agent-gate-prompt <prompt>", "Custom gate prompt").option("--tts-voice <id>", "ElevenLabs voice ID").option("--tts-model <id>", "ElevenLabs model ID").option("--access-mode <mode>", "Access mode: disabled, blocklist, or allowlist").option("--reaction-ack <mode>", "Reaction ack mode (on|off)").option("--reaction-ack-emoji <json>", "Per-channel emoji map as JSON").option("--ack-timeout <ms>", "Ack timeout in milliseconds", (v) => Number.parseInt(v, 10)).option("--token <token>", "Generic bot token (auto-resolves to channel-specific field)").option("--telegram-token <token>", "Telegram bot token").option("--discord-token <token>", "Discord bot token").option("--slack-bot-token <token>", "Slack bot token").option("--slack-app-token <token>", "Slack app token").option("--gupshup-api-key <key>", "Gupshup API key").option("--gupshup-app-name <name>", "Gupshup app name").option("--gupshup-source-phone <phone>", "Gupshup source phone (E.164)").option("--gupshup-webhook-verify-token <token>", "Gupshup webhook verify token").option("--is-default", "Set as default instance for channel").action(async (options) => {
81581
82275
  const channel = options.channel;
81582
82276
  if (!VALID_CHANNELS2.includes(channel)) {
81583
82277
  error(`Invalid channel: ${channel}`, { validChannels: VALID_CHANNELS2 });
@@ -82173,7 +82867,9 @@ function createInstancesCommand() {
82173
82867
  }
82174
82868
 
82175
82869
  // src/commands/journey.ts
82870
+ init_source();
82176
82871
  init_config();
82872
+ init_output();
82177
82873
  var STAGE_LABELS = {
82178
82874
  T0: "Platform received",
82179
82875
  T1: "Plugin received",
@@ -82387,6 +83083,7 @@ function createJourneyCommand() {
82387
83083
  }
82388
83084
 
82389
83085
  // src/commands/keys.ts
83086
+ init_output();
82390
83087
  function formatKeyRow(key) {
82391
83088
  return {
82392
83089
  id: key.id.slice(0, 8),
@@ -82542,7 +83239,133 @@ function createKeysCommand() {
82542
83239
  return keys;
82543
83240
  }
82544
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
+
82545
83367
  // src/commands/logs.ts
83368
+ init_output();
82546
83369
  async function streamProcessLogs(service, lines, follow) {
82547
83370
  if (!await isPm2Available()) {
82548
83371
  pm2NotFoundError();
@@ -82593,11 +83416,12 @@ function createLogsCommand() {
82593
83416
  }
82594
83417
 
82595
83418
  // src/commands/media.ts
82596
- import { createWriteStream, existsSync as existsSync4, mkdirSync as mkdirSync3, statSync } from "fs";
82597
- 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";
82598
83421
  import { Readable } from "stream";
82599
83422
  import { pipeline } from "stream/promises";
82600
83423
  init_config();
83424
+ init_output();
82601
83425
  function buildUrl(baseUrl, path, query) {
82602
83426
  let url = `${baseUrl}/api/v2/${path}`;
82603
83427
  if (!query)
@@ -82647,7 +83471,7 @@ function resolveDownloadUrl(baseUrl, downloadUrl) {
82647
83471
  return `${base}${path}`;
82648
83472
  }
82649
83473
  function resolveOutputPath(outputPath, result) {
82650
- const fallbackName = result.mediaLocalPath ? basename(result.mediaLocalPath) : "";
83474
+ const fallbackName = result.mediaLocalPath ? basename4(result.mediaLocalPath) : "";
82651
83475
  const filename = fallbackName || `${result.messageId}`;
82652
83476
  if (!outputPath)
82653
83477
  return resolve(process.cwd(), filename);
@@ -82655,13 +83479,13 @@ function resolveOutputPath(outputPath, result) {
82655
83479
  const resolved = resolve(outputPath);
82656
83480
  if (isDirHint)
82657
83481
  return resolve(resolved, filename);
82658
- if (existsSync4(resolved) && statSync(resolved).isDirectory())
83482
+ if (existsSync5(resolved) && statSync(resolved).isDirectory())
82659
83483
  return resolve(resolved, filename);
82660
83484
  return resolved;
82661
83485
  }
82662
83486
  async function downloadToFile(url, apiKey, destinationPath) {
82663
- const destDir = dirname3(destinationPath);
82664
- if (!existsSync4(destDir))
83487
+ const destDir = dirname4(destinationPath);
83488
+ if (!existsSync5(destDir))
82665
83489
  mkdirSync3(destDir, { recursive: true });
82666
83490
  const resp = await fetch(url, {
82667
83491
  method: "GET",
@@ -82863,6 +83687,7 @@ function createMediaCommand() {
82863
83687
  }
82864
83688
 
82865
83689
  // src/commands/messages.ts
83690
+ init_output();
82866
83691
  function parseDuration(duration) {
82867
83692
  const now = new Date;
82868
83693
  const match = duration.match(/^(\d+)([dhm])$/);
@@ -83194,7 +84019,37 @@ function createMessagesCommand() {
83194
84019
  return messages;
83195
84020
  }
83196
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
+
83197
84051
  // src/commands/payloads.ts
84052
+ init_output();
83198
84053
  var VALID_STAGES = ["webhook_raw", "agent_request", "agent_response", "channel_send", "error"];
83199
84054
  var boolDisplay = (v) => v ? "yes" : "no";
83200
84055
  var parseBool = (v) => v === "true" ? true : v === "false" ? false : undefined;
@@ -83297,6 +84152,7 @@ function createPayloadsCommand() {
83297
84152
  }
83298
84153
 
83299
84154
  // src/commands/persons.ts
84155
+ init_output();
83300
84156
  function createPersonsCommand() {
83301
84157
  const persons = new Command("persons").description("Search and manage persons");
83302
84158
  persons.command("search <query>").description("Search for persons").option("--limit <n>", "Limit results", (v) => Number.parseInt(v, 10), 20).action(async (query, options) => {
@@ -83306,7 +84162,8 @@ function createPersonsCommand() {
83306
84162
  search: query,
83307
84163
  limit: options.limit
83308
84164
  });
83309
- const items = results.map((p) => ({
84165
+ const persons2 = results;
84166
+ const items = persons2.map((p) => ({
83310
84167
  id: p.id,
83311
84168
  displayName: p.displayName ?? "-",
83312
84169
  email: p.email ?? "-",
@@ -83340,10 +84197,77 @@ function createPersonsCommand() {
83340
84197
  error(`Failed to get presence: ${message}`, undefined, 3);
83341
84198
  }
83342
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
+ });
83343
84266
  return persons;
83344
84267
  }
83345
84268
 
83346
84269
  // src/commands/prompts.ts
84270
+ init_output();
83347
84271
  var PROMPT_MAP = {
83348
84272
  image: "prompt.image_description",
83349
84273
  video: "prompt.video_description",
@@ -91453,7 +92377,7 @@ var log15 = createLogger("provider:a2a");
91453
92377
  var import_nats4 = __toESM(require_mod4(), 1);
91454
92378
  import { mkdir, writeFile } from "fs/promises";
91455
92379
  import { homedir as homedir3 } from "os";
91456
- import { join as join5 } from "path";
92380
+ import { join as join6 } from "path";
91457
92381
  var log16 = createLogger("provider:nats-genie");
91458
92382
 
91459
92383
  class NatsGenieProvider {
@@ -91461,7 +92385,7 @@ class NatsGenieProvider {
91461
92385
  name;
91462
92386
  config;
91463
92387
  schema = "nats-genie";
91464
- mode = "fire-and-forget";
92388
+ mode;
91465
92389
  nc = null;
91466
92390
  sc = import_nats4.StringCodec();
91467
92391
  replySubscription = null;
@@ -91469,6 +92393,7 @@ class NatsGenieProvider {
91469
92393
  this.id = id;
91470
92394
  this.name = name;
91471
92395
  this.config = config2;
92396
+ this.mode = config2.mode ?? "fire-and-forget";
91472
92397
  }
91473
92398
  canHandle(_trigger) {
91474
92399
  return true;
@@ -91493,7 +92418,8 @@ class NatsGenieProvider {
91493
92418
  timestamp: new Date().toISOString(),
91494
92419
  traceId: context.traceId,
91495
92420
  messageId: context.source.messageId,
91496
- files: context.content.files
92421
+ files: context.content.files,
92422
+ env: context.env
91497
92423
  };
91498
92424
  try {
91499
92425
  await this.ensureConnected();
@@ -91606,10 +92532,10 @@ class NatsGenieProvider {
91606
92532
  }
91607
92533
  async writeDeadLetter(payload, error2) {
91608
92534
  try {
91609
- const dlDir = join5(homedir3(), ".omni", "dead-letters");
92535
+ const dlDir = join6(homedir3(), ".omni", "dead-letters");
91610
92536
  await mkdir(dlDir, { recursive: true });
91611
92537
  const filename = `nats-genie-${Date.now()}-${payload.chatId}.json`;
91612
- await writeFile(join5(dlDir, filename), JSON.stringify({
92538
+ await writeFile(join6(dlDir, filename), JSON.stringify({
91613
92539
  payload,
91614
92540
  error: error2 instanceof Error ? error2.message : String(error2),
91615
92541
  timestamp: new Date().toISOString()
@@ -91951,14 +92877,18 @@ class HookRegistry {
91951
92877
  }
91952
92878
  // ../core/src/hooks/executor.ts
91953
92879
  var log17 = createLogger("hooks:executor");
92880
+ // src/commands/providers.ts
92881
+ init_output();
92882
+
91954
92883
  // src/commands/providers-setup.ts
91955
92884
  import { execFileSync as execFileSync2, execSync } from "child_process";
91956
92885
  import * as nodeCrypto2 from "crypto";
91957
- 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";
91958
92887
  import { homedir as homedir4 } from "os";
91959
- import { dirname as dirname4, resolve as resolve2 } from "path";
92888
+ import { dirname as dirname5, resolve as resolve2 } from "path";
91960
92889
  import { createInterface as createInterface3 } from "readline";
91961
92890
  init_config();
92891
+ init_output();
91962
92892
  async function promptLine2(question, defaultValue = "") {
91963
92893
  const rl = createInterface3({
91964
92894
  input: process.stdin,
@@ -92184,16 +93114,16 @@ async function pairDevice(gatewayUrl, gatewayToken, keypair, spinner) {
92184
93114
  var OPENCLAW_CONFIG_PATH = resolve2(homedir4(), ".openclaw", "openclaw.json");
92185
93115
  var PLUGIN_MARKER = "plugin-openclaw/omni.ts";
92186
93116
  function readOpenClawConfig(configPath) {
92187
- if (!existsSync5(configPath))
93117
+ if (!existsSync6(configPath))
92188
93118
  return {};
92189
- const raw2 = readFileSync3(configPath, "utf-8").trim();
93119
+ const raw2 = readFileSync4(configPath, "utf-8").trim();
92190
93120
  if (!raw2)
92191
93121
  return {};
92192
93122
  return JSON.parse(raw2);
92193
93123
  }
92194
93124
  function writeOpenClawConfig(configPath, config2) {
92195
- mkdirSync4(dirname4(configPath), { recursive: true, mode: 448 });
92196
- writeFileSync3(configPath, `${JSON.stringify(config2, null, 2)}
93125
+ mkdirSync4(dirname5(configPath), { recursive: true, mode: 448 });
93126
+ writeFileSync5(configPath, `${JSON.stringify(config2, null, 2)}
92197
93127
  `, { mode: 384 });
92198
93128
  }
92199
93129
  function isPluginRegistered(config2, marker, pluginPath) {
@@ -92225,10 +93155,10 @@ function isValidUuid(value) {
92225
93155
  }
92226
93156
  function resolvePluginPath(explicit) {
92227
93157
  if (explicit) {
92228
- return existsSync5(explicit) ? resolve2(explicit) : null;
93158
+ return existsSync6(explicit) ? resolve2(explicit) : null;
92229
93159
  }
92230
93160
  const cwdCandidate = resolve2(process.cwd(), "packages/plugin-openclaw/omni.ts");
92231
- return existsSync5(cwdCandidate) ? cwdCandidate : null;
93161
+ return existsSync6(cwdCandidate) ? cwdCandidate : null;
92232
93162
  }
92233
93163
  function registerPlugin(config2, pluginPath, configPath) {
92234
93164
  if (hasOpenClawCli()) {
@@ -92739,10 +93669,47 @@ function createProvidersCommand() {
92739
93669
  return providers2;
92740
93670
  }
92741
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
+
92742
93707
  // src/commands/replay.ts
92743
93708
  init_config();
92744
93709
 
92745
93710
  // src/help.ts
93711
+ init_source();
93712
+ init_output();
92746
93713
  function c2() {
92747
93714
  if (areColorsEnabled()) {
92748
93715
  return source_default;
@@ -92788,6 +93755,7 @@ ${cmdLines.join(`
92788
93755
  }
92789
93756
 
92790
93757
  // src/commands/replay.ts
93758
+ init_output();
92791
93759
  var options = [
92792
93760
  {
92793
93761
  flags: "-s, --since <timestamp>",
@@ -92876,8 +93844,9 @@ ${formatExamples(examples)}`);
92876
93844
  }
92877
93845
 
92878
93846
  // src/commands/restart.ts
92879
- import { join as join6 } from "path";
93847
+ import { join as join7 } from "path";
92880
93848
  init_config();
93849
+ init_output();
92881
93850
  var RESTART_HEALTH_TIMEOUT_MS = 1e4;
92882
93851
  function buildApiRuntimeEnv2() {
92883
93852
  const serverConfig = loadServerConfig();
@@ -92886,9 +93855,9 @@ function buildApiRuntimeEnv2() {
92886
93855
  API_PORT: String(serverConfig.port),
92887
93856
  DATABASE_URL: serverConfig.databaseUrl,
92888
93857
  OMNI_API_KEY: config2.apiKey ?? "",
92889
- MEDIA_STORAGE_PATH: join6(serverConfig.dataDir, "media"),
93858
+ MEDIA_STORAGE_PATH: join7(serverConfig.dataDir, "media"),
92890
93859
  PGSERVE_EMBEDDED: "true",
92891
- PGSERVE_DATA: join6(serverConfig.dataDir, "pgserve"),
93860
+ PGSERVE_DATA: join7(serverConfig.dataDir, "pgserve"),
92892
93861
  NATS_URL: "nats://localhost:4222",
92893
93862
  NODE_ENV: serverConfig.nodeEnv,
92894
93863
  LOG_LEVEL: serverConfig.logLevel
@@ -92921,6 +93890,7 @@ function createRestartCommand() {
92921
93890
 
92922
93891
  // src/commands/resync.ts
92923
93892
  init_config();
93893
+ init_output();
92924
93894
  var options2 = [
92925
93895
  { flags: "-i, --instance <id>", description: "Instance ID or name to resync" },
92926
93896
  { flags: "-a, --all", description: "Resync all connected instances" },
@@ -93028,12 +93998,172 @@ ${formatExamples(examples2)}`);
93028
93998
  return cmd;
93029
93999
  }
93030
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
+
93031
94158
  // src/commands/send.ts
93032
- import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
93033
- 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();
93034
94162
  init_config();
93035
- function getMediaType(path) {
93036
- const ext = extname(path).toLowerCase();
94163
+ init_output();
94164
+ init_output();
94165
+ function getMediaType2(path) {
94166
+ const ext = extname5(path).toLowerCase();
93037
94167
  const imageExts = [".jpg", ".jpeg", ".png", ".gif", ".webp"];
93038
94168
  const audioExts = [".mp3", ".wav", ".ogg", ".m4a", ".opus"];
93039
94169
  const videoExts = [".mp4", ".webm", ".mov", ".avi"];
@@ -93046,7 +94176,7 @@ function getMediaType(path) {
93046
94176
  return "document";
93047
94177
  }
93048
94178
  function readFileAsBase64(path) {
93049
- const buffer2 = readFileSync4(path);
94179
+ const buffer2 = readFileSync6(path);
93050
94180
  return buffer2.toString("base64");
93051
94181
  }
93052
94182
  var messageSenders = {
@@ -93067,13 +94197,13 @@ var messageSenders = {
93067
94197
  const { to, media } = options3;
93068
94198
  if (!to || !media)
93069
94199
  return;
93070
- if (!existsSync6(media)) {
94200
+ if (!existsSync8(media)) {
93071
94201
  error(`File not found: ${media}`);
93072
94202
  return;
93073
94203
  }
93074
- const mediaType = getMediaType(media);
94204
+ const mediaType = getMediaType2(media);
93075
94205
  const base64 = readFileAsBase64(media);
93076
- const filename = basename2(media);
94206
+ const filename = basename5(media);
93077
94207
  const result = await client.messages.sendMedia({
93078
94208
  instanceId,
93079
94209
  to,
@@ -93398,7 +94528,21 @@ function createSendCommand() {
93398
94528
  send.configureHelp({
93399
94529
  formatHelp: () => buildGroupedSendHelp()
93400
94530
  });
93401
- 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
+ }
93402
94546
  const messageType = getMessageType(options3);
93403
94547
  if (!messageType) {
93404
94548
  error("No message type specified. Use --text, --media, --reaction, --forward, etc.");
@@ -93416,6 +94560,7 @@ function createSendCommand() {
93416
94560
  }
93417
94561
 
93418
94562
  // src/commands/settings.ts
94563
+ init_output();
93419
94564
  function createSettingsCommand() {
93420
94565
  const settings = new Command("settings").description("Manage API settings");
93421
94566
  settings.command("list").description("List all settings").option("--category <category>", "Filter by category").action(async (options3) => {
@@ -93473,11 +94618,122 @@ function createSettingsCommand() {
93473
94618
  return settings;
93474
94619
  }
93475
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
+
93476
94731
  // src/commands/start.ts
93477
- import { existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
94732
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5 } from "fs";
93478
94733
  import { homedir as homedir5 } from "os";
93479
- import { join as join7 } from "path";
94734
+ import { join as join8 } from "path";
93480
94735
  init_config();
94736
+ init_output();
93481
94737
  var START_HEALTH_TIMEOUT_MS = 1e4;
93482
94738
  function buildApiRuntimeEnv3() {
93483
94739
  const serverConfig = loadServerConfig();
@@ -93486,10 +94742,10 @@ function buildApiRuntimeEnv3() {
93486
94742
  API_PORT: String(serverConfig.port),
93487
94743
  DATABASE_URL: serverConfig.databaseUrl,
93488
94744
  OMNI_API_KEY: config2.apiKey ?? "",
93489
- MEDIA_STORAGE_PATH: join7(serverConfig.dataDir, "media"),
93490
- OMNI_PACKAGES_DIR: join7(serverConfig.dataDir, "packages"),
94745
+ MEDIA_STORAGE_PATH: join8(serverConfig.dataDir, "media"),
94746
+ OMNI_PACKAGES_DIR: join8(serverConfig.dataDir, "packages"),
93491
94747
  PGSERVE_EMBEDDED: "true",
93492
- PGSERVE_DATA: join7(serverConfig.dataDir, "pgserve"),
94748
+ PGSERVE_DATA: join8(serverConfig.dataDir, "pgserve"),
93493
94749
  NATS_URL: "nats://localhost:4222",
93494
94750
  NODE_ENV: serverConfig.nodeEnv,
93495
94751
  LOG_LEVEL: serverConfig.logLevel
@@ -93500,7 +94756,7 @@ async function runStart() {
93500
94756
  pm2NotFoundError();
93501
94757
  }
93502
94758
  const bundlePath = getServerBundlePath();
93503
- if (!existsSync7(bundlePath)) {
94759
+ if (!existsSync9(bundlePath)) {
93504
94760
  bundleNotFoundError(bundlePath);
93505
94761
  }
93506
94762
  const serverConfig = loadServerConfig();
@@ -93513,10 +94769,10 @@ async function runStart() {
93513
94769
  error(`Failed to start ${PM2_PROCESSES.api} (pm2 exit code ${apiCode})`, undefined, 1);
93514
94770
  return;
93515
94771
  }
93516
- const natsPath = join7(homedir5(), ".omni", "nats-server");
93517
- if (existsSync7(natsPath)) {
94772
+ const natsPath = join8(homedir5(), ".omni", "nats-server");
94773
+ if (existsSync9(natsPath)) {
93518
94774
  info(`Starting ${PM2_PROCESSES.nats}...`);
93519
- const natsDataDir = join7(serverConfig.dataDir, "nats");
94775
+ const natsDataDir = join8(serverConfig.dataDir, "nats");
93520
94776
  mkdirSync5(natsDataDir, { recursive: true });
93521
94777
  const natsCode = await runPm2(["start", natsPath, "--name", PM2_PROCESSES.nats, "--", "-js", "-sd", natsDataDir]);
93522
94778
  if (natsCode !== 0) {
@@ -93540,6 +94796,7 @@ function createStartCommand() {
93540
94796
 
93541
94797
  // src/commands/status.ts
93542
94798
  init_config();
94799
+ init_output();
93543
94800
  function formatUptime(ms) {
93544
94801
  if (ms === undefined || ms === 0)
93545
94802
  return "-";
@@ -93664,6 +94921,7 @@ function createStatusCommand() {
93664
94921
  }
93665
94922
 
93666
94923
  // src/commands/stop.ts
94924
+ init_output();
93667
94925
  var LEGACY_PROCESSES = ["omni-v2-api", "omni-v2-nats"];
93668
94926
  async function runStop() {
93669
94927
  if (!await isPm2Available()) {
@@ -93683,6 +94941,7 @@ function createStopCommand() {
93683
94941
  }
93684
94942
 
93685
94943
  // src/commands/tts.ts
94944
+ init_output();
93686
94945
  function createTtsCommand() {
93687
94946
  const tts = new Command("tts").description("Text-to-speech operations");
93688
94947
  tts.command("voices").description("List available TTS voices").action(async () => {
@@ -93710,6 +94969,7 @@ function createTtsCommand() {
93710
94969
  // src/commands/update.ts
93711
94970
  import { createInterface as createInterface4 } from "readline";
93712
94971
  init_config();
94972
+ init_output();
93713
94973
  var PACKAGE_NAME = "@automagik/omni";
93714
94974
  var UPDATE_HEALTH_TIMEOUT_MS = 1e4;
93715
94975
  async function fetchLatestVersion() {
@@ -93859,7 +95119,29 @@ Behavior:
93859
95119
  `).action(runUpdate);
93860
95120
  }
93861
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
+
93862
95143
  // src/commands/webhooks.ts
95144
+ init_output();
93863
95145
  function createWebhooksCommand() {
93864
95146
  const webhooks = new Command("webhooks").description("Manage webhook sources");
93865
95147
  webhooks.command("list").description("List webhook sources").option("--enabled", "Show only enabled sources").option("--disabled", "Show only disabled sources").action(async (options3) => {
@@ -93983,11 +95265,38 @@ function createWebhooksCommand() {
93983
95265
  return webhooks;
93984
95266
  }
93985
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
+
93986
95292
  // src/index.ts
93987
95293
  init_config();
95294
+ init_output();
93988
95295
 
93989
95296
  // src/status.ts
95297
+ init_source();
93990
95298
  init_config();
95299
+ init_output();
93991
95300
  function c4() {
93992
95301
  if (areColorsEnabled()) {
93993
95302
  return source_default;
@@ -94154,6 +95463,48 @@ var COMMANDS = [
94154
95463
  helpGroup: "Core",
94155
95464
  helpDescription: "Send message (text, media, location, poll)"
94156
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
+ },
94157
95508
  { create: createChatsCommand, category: "core", helpGroup: "Core", helpDescription: "List and manage conversations" },
94158
95509
  {
94159
95510
  create: createMessagesCommand,
@@ -94167,6 +95518,36 @@ var COMMANDS = [
94167
95518
  helpGroup: "Core",
94168
95519
  helpDescription: "Text-to-speech operations"
94169
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
+ },
94170
95551
  {
94171
95552
  create: createChannelsCommand,
94172
95553
  category: "core",