@mingxy/ocosay 1.0.35 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/config.js +2 -0
  3. package/dist/config.js.map +1 -1
  4. package/dist/core/backends/index.d.ts.map +1 -1
  5. package/dist/core/backends/index.js +8 -3
  6. package/dist/core/backends/index.js.map +1 -1
  7. package/dist/core/speaker.d.ts.map +1 -1
  8. package/dist/core/speaker.js +1 -0
  9. package/dist/core/speaker.js.map +1 -1
  10. package/dist/core/streaming-synthesizer.d.ts.map +1 -1
  11. package/dist/core/streaming-synthesizer.js +2 -0
  12. package/dist/core/streaming-synthesizer.js.map +1 -1
  13. package/dist/index.d.ts +0 -13
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -23
  16. package/dist/index.js.map +1 -1
  17. package/dist/plugin.d.ts.map +1 -1
  18. package/dist/plugin.js +956 -575
  19. package/dist/plugin.js.map +4 -4
  20. package/dist/providers/minimax.d.ts.map +1 -1
  21. package/dist/providers/minimax.js +43 -20
  22. package/dist/providers/minimax.js.map +1 -1
  23. package/dist/services/notification-service.d.ts +17 -0
  24. package/dist/services/notification-service.d.ts.map +1 -0
  25. package/dist/services/notification-service.js +74 -0
  26. package/dist/services/notification-service.js.map +1 -0
  27. package/dist/services/speaker-service.d.ts +34 -0
  28. package/dist/services/speaker-service.d.ts.map +1 -0
  29. package/dist/services/speaker-service.js +74 -0
  30. package/dist/services/speaker-service.js.map +1 -0
  31. package/dist/services/streaming-service.d.ts +109 -0
  32. package/dist/services/streaming-service.d.ts.map +1 -0
  33. package/dist/services/streaming-service.js +281 -0
  34. package/dist/services/streaming-service.js.map +1 -0
  35. package/dist/tools/tts.d.ts.map +1 -1
  36. package/dist/tools/tts.js +30 -18
  37. package/dist/tools/tts.js.map +1 -1
  38. package/package.json +2 -2
  39. package/tsconfig.jest.json +21 -0
  40. package/dist/core/logger.d.ts +0 -46
  41. package/dist/core/logger.d.ts.map +0 -1
  42. package/dist/core/logger.js +0 -126
  43. package/dist/core/logger.js.map +0 -1
package/dist/plugin.js CHANGED
@@ -593,17 +593,17 @@ var require_howler = __commonJS({
593
593
  var duration = Math.max(0, (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1e3 - seek);
594
594
  var timeout = duration * 1e3 / Math.abs(sound._rate);
595
595
  var start = self._sprite[sprite][0] / 1e3;
596
- var stop2 = (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1e3;
596
+ var stop3 = (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1e3;
597
597
  sound._sprite = sprite;
598
598
  sound._ended = false;
599
599
  var setParams = function() {
600
600
  sound._paused = false;
601
601
  sound._seek = seek;
602
602
  sound._start = start;
603
- sound._stop = stop2;
603
+ sound._stop = stop3;
604
604
  sound._loop = !!(sound._loop || self._sprite[sprite][2]);
605
605
  };
606
- if (seek >= stop2) {
606
+ if (seek >= stop3) {
607
607
  self._ended(sound);
608
608
  return;
609
609
  }
@@ -3418,7 +3418,7 @@ var require_sonic_boom = __commonJS({
3418
3418
  "node_modules/sonic-boom/index.js"(exports, module) {
3419
3419
  "use strict";
3420
3420
  var fs3 = __require("fs");
3421
- var EventEmitter6 = __require("events");
3421
+ var EventEmitter7 = __require("events");
3422
3422
  var inherits = __require("util").inherits;
3423
3423
  var path2 = __require("path");
3424
3424
  var sleep = require_atomic_sleep();
@@ -3655,7 +3655,7 @@ var require_sonic_boom = __commonJS({
3655
3655
  sonic._asyncDrainScheduled = false;
3656
3656
  sonic.emit("drain");
3657
3657
  }
3658
- inherits(SonicBoom, EventEmitter6);
3658
+ inherits(SonicBoom, EventEmitter7);
3659
3659
  function mergeBuf(bufs, len) {
3660
3660
  if (bufs.length === 0) {
3661
3661
  return kEmptyBuffer;
@@ -4223,7 +4223,7 @@ var require_thread_stream = __commonJS({
4223
4223
  "node_modules/thread-stream/index.js"(exports, module) {
4224
4224
  "use strict";
4225
4225
  var { version } = require_package();
4226
- var { EventEmitter: EventEmitter6 } = __require("events");
4226
+ var { EventEmitter: EventEmitter7 } = __require("events");
4227
4227
  var { Worker } = __require("worker_threads");
4228
4228
  var { join: join8 } = __require("path");
4229
4229
  var { pathToFileURL } = __require("url");
@@ -4258,7 +4258,7 @@ var require_thread_stream = __commonJS({
4258
4258
  }
4259
4259
  worker.terminate();
4260
4260
  });
4261
- function createWorker(stream, opts) {
4261
+ function createWorker(stream2, opts) {
4262
4262
  const { filename, workerData } = opts;
4263
4263
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
4264
4264
  const toExecute = bundlerOverrides["thread-stream-worker"] || join8(__dirname, "lib", "worker.js");
@@ -4267,8 +4267,8 @@ var require_thread_stream = __commonJS({
4267
4267
  trackUnmanagedFds: false,
4268
4268
  workerData: {
4269
4269
  filename: filename.indexOf("file://") === 0 ? filename : pathToFileURL(filename).href,
4270
- dataBuf: stream[kImpl].dataBuf,
4271
- stateBuf: stream[kImpl].stateBuf,
4270
+ dataBuf: stream2[kImpl].dataBuf,
4271
+ stateBuf: stream2[kImpl].stateBuf,
4272
4272
  workerData: {
4273
4273
  $context: {
4274
4274
  threadStreamVersion: version
@@ -4277,111 +4277,111 @@ var require_thread_stream = __commonJS({
4277
4277
  }
4278
4278
  }
4279
4279
  });
4280
- worker.stream = new FakeWeakRef(stream);
4280
+ worker.stream = new FakeWeakRef(stream2);
4281
4281
  worker.on("message", onWorkerMessage);
4282
4282
  worker.on("exit", onWorkerExit);
4283
- registry.register(stream, worker);
4283
+ registry.register(stream2, worker);
4284
4284
  return worker;
4285
4285
  }
4286
- function drain(stream) {
4287
- assert(!stream[kImpl].sync);
4288
- if (stream[kImpl].needDrain) {
4289
- stream[kImpl].needDrain = false;
4290
- stream.emit("drain");
4286
+ function drain(stream2) {
4287
+ assert(!stream2[kImpl].sync);
4288
+ if (stream2[kImpl].needDrain) {
4289
+ stream2[kImpl].needDrain = false;
4290
+ stream2.emit("drain");
4291
4291
  }
4292
4292
  }
4293
- function nextFlush(stream) {
4294
- const writeIndex = Atomics.load(stream[kImpl].state, WRITE_INDEX);
4295
- let leftover = stream[kImpl].data.length - writeIndex;
4293
+ function nextFlush(stream2) {
4294
+ const writeIndex = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
4295
+ let leftover = stream2[kImpl].data.length - writeIndex;
4296
4296
  if (leftover > 0) {
4297
- if (stream[kImpl].buf.length === 0) {
4298
- stream[kImpl].flushing = false;
4299
- if (stream[kImpl].ending) {
4300
- end(stream);
4301
- } else if (stream[kImpl].needDrain) {
4302
- process.nextTick(drain, stream);
4297
+ if (stream2[kImpl].buf.length === 0) {
4298
+ stream2[kImpl].flushing = false;
4299
+ if (stream2[kImpl].ending) {
4300
+ end(stream2);
4301
+ } else if (stream2[kImpl].needDrain) {
4302
+ process.nextTick(drain, stream2);
4303
4303
  }
4304
4304
  return;
4305
4305
  }
4306
- let toWrite = stream[kImpl].buf.slice(0, leftover);
4306
+ let toWrite = stream2[kImpl].buf.slice(0, leftover);
4307
4307
  let toWriteBytes = Buffer.byteLength(toWrite);
4308
4308
  if (toWriteBytes <= leftover) {
4309
- stream[kImpl].buf = stream[kImpl].buf.slice(leftover);
4310
- write(stream, toWrite, nextFlush.bind(null, stream));
4309
+ stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
4310
+ write(stream2, toWrite, nextFlush.bind(null, stream2));
4311
4311
  } else {
4312
- stream.flush(() => {
4313
- if (stream.destroyed) {
4312
+ stream2.flush(() => {
4313
+ if (stream2.destroyed) {
4314
4314
  return;
4315
4315
  }
4316
- Atomics.store(stream[kImpl].state, READ_INDEX, 0);
4317
- Atomics.store(stream[kImpl].state, WRITE_INDEX, 0);
4318
- Atomics.notify(stream[kImpl].state, READ_INDEX);
4319
- while (toWriteBytes > stream[kImpl].data.length) {
4316
+ Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
4317
+ Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
4318
+ Atomics.notify(stream2[kImpl].state, READ_INDEX);
4319
+ while (toWriteBytes > stream2[kImpl].data.length) {
4320
4320
  leftover = leftover / 2;
4321
- toWrite = stream[kImpl].buf.slice(0, leftover);
4321
+ toWrite = stream2[kImpl].buf.slice(0, leftover);
4322
4322
  toWriteBytes = Buffer.byteLength(toWrite);
4323
4323
  }
4324
- stream[kImpl].buf = stream[kImpl].buf.slice(leftover);
4325
- write(stream, toWrite, nextFlush.bind(null, stream));
4324
+ stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
4325
+ write(stream2, toWrite, nextFlush.bind(null, stream2));
4326
4326
  });
4327
4327
  }
4328
4328
  } else if (leftover === 0) {
4329
- if (writeIndex === 0 && stream[kImpl].buf.length === 0) {
4329
+ if (writeIndex === 0 && stream2[kImpl].buf.length === 0) {
4330
4330
  return;
4331
4331
  }
4332
- stream.flush(() => {
4333
- Atomics.store(stream[kImpl].state, READ_INDEX, 0);
4334
- Atomics.store(stream[kImpl].state, WRITE_INDEX, 0);
4335
- Atomics.notify(stream[kImpl].state, READ_INDEX);
4336
- nextFlush(stream);
4332
+ stream2.flush(() => {
4333
+ Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
4334
+ Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
4335
+ Atomics.notify(stream2[kImpl].state, READ_INDEX);
4336
+ nextFlush(stream2);
4337
4337
  });
4338
4338
  } else {
4339
- destroy(stream, new Error("overwritten"));
4339
+ destroy(stream2, new Error("overwritten"));
4340
4340
  }
4341
4341
  }
4342
4342
  function onWorkerMessage(msg) {
4343
- const stream = this.stream.deref();
4344
- if (stream === void 0) {
4343
+ const stream2 = this.stream.deref();
4344
+ if (stream2 === void 0) {
4345
4345
  this.exited = true;
4346
4346
  this.terminate();
4347
4347
  return;
4348
4348
  }
4349
4349
  switch (msg.code) {
4350
4350
  case "READY":
4351
- this.stream = new WeakRef2(stream);
4352
- stream.flush(() => {
4353
- stream[kImpl].ready = true;
4354
- stream.emit("ready");
4351
+ this.stream = new WeakRef2(stream2);
4352
+ stream2.flush(() => {
4353
+ stream2[kImpl].ready = true;
4354
+ stream2.emit("ready");
4355
4355
  });
4356
4356
  break;
4357
4357
  case "ERROR":
4358
- destroy(stream, msg.err);
4358
+ destroy(stream2, msg.err);
4359
4359
  break;
4360
4360
  case "EVENT":
4361
4361
  if (Array.isArray(msg.args)) {
4362
- stream.emit(msg.name, ...msg.args);
4362
+ stream2.emit(msg.name, ...msg.args);
4363
4363
  } else {
4364
- stream.emit(msg.name, msg.args);
4364
+ stream2.emit(msg.name, msg.args);
4365
4365
  }
4366
4366
  break;
4367
4367
  case "WARNING":
4368
4368
  process.emitWarning(msg.err);
4369
4369
  break;
4370
4370
  default:
4371
- destroy(stream, new Error("this should not happen: " + msg.code));
4371
+ destroy(stream2, new Error("this should not happen: " + msg.code));
4372
4372
  }
4373
4373
  }
4374
4374
  function onWorkerExit(code) {
4375
- const stream = this.stream.deref();
4376
- if (stream === void 0) {
4375
+ const stream2 = this.stream.deref();
4376
+ if (stream2 === void 0) {
4377
4377
  return;
4378
4378
  }
4379
- registry.unregister(stream);
4380
- stream.worker.exited = true;
4381
- stream.worker.off("exit", onWorkerExit);
4382
- destroy(stream, code !== 0 ? new Error("the worker thread exited") : null);
4379
+ registry.unregister(stream2);
4380
+ stream2.worker.exited = true;
4381
+ stream2.worker.off("exit", onWorkerExit);
4382
+ destroy(stream2, code !== 0 ? new Error("the worker thread exited") : null);
4383
4383
  }
4384
- var ThreadStream = class extends EventEmitter6 {
4384
+ var ThreadStream = class extends EventEmitter7 {
4385
4385
  constructor(opts = {}) {
4386
4386
  super();
4387
4387
  if (opts.bufferSize < 4) {
@@ -4512,127 +4512,127 @@ var require_thread_stream = __commonJS({
4512
4512
  return this[kImpl].errored;
4513
4513
  }
4514
4514
  };
4515
- function error(stream, err) {
4515
+ function error(stream2, err) {
4516
4516
  setImmediate(() => {
4517
- stream.emit("error", err);
4517
+ stream2.emit("error", err);
4518
4518
  });
4519
4519
  }
4520
- function destroy(stream, err) {
4521
- if (stream[kImpl].destroyed) {
4520
+ function destroy(stream2, err) {
4521
+ if (stream2[kImpl].destroyed) {
4522
4522
  return;
4523
4523
  }
4524
- stream[kImpl].destroyed = true;
4524
+ stream2[kImpl].destroyed = true;
4525
4525
  if (err) {
4526
- stream[kImpl].errored = err;
4527
- error(stream, err);
4526
+ stream2[kImpl].errored = err;
4527
+ error(stream2, err);
4528
4528
  }
4529
- if (!stream.worker.exited) {
4530
- stream.worker.terminate().catch(() => {
4529
+ if (!stream2.worker.exited) {
4530
+ stream2.worker.terminate().catch(() => {
4531
4531
  }).then(() => {
4532
- stream[kImpl].closed = true;
4533
- stream.emit("close");
4532
+ stream2[kImpl].closed = true;
4533
+ stream2.emit("close");
4534
4534
  });
4535
4535
  } else {
4536
4536
  setImmediate(() => {
4537
- stream[kImpl].closed = true;
4538
- stream.emit("close");
4537
+ stream2[kImpl].closed = true;
4538
+ stream2.emit("close");
4539
4539
  });
4540
4540
  }
4541
4541
  }
4542
- function write(stream, data, cb) {
4543
- const current = Atomics.load(stream[kImpl].state, WRITE_INDEX);
4542
+ function write(stream2, data, cb) {
4543
+ const current = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
4544
4544
  const length = Buffer.byteLength(data);
4545
- stream[kImpl].data.write(data, current);
4546
- Atomics.store(stream[kImpl].state, WRITE_INDEX, current + length);
4547
- Atomics.notify(stream[kImpl].state, WRITE_INDEX);
4545
+ stream2[kImpl].data.write(data, current);
4546
+ Atomics.store(stream2[kImpl].state, WRITE_INDEX, current + length);
4547
+ Atomics.notify(stream2[kImpl].state, WRITE_INDEX);
4548
4548
  cb();
4549
4549
  return true;
4550
4550
  }
4551
- function end(stream) {
4552
- if (stream[kImpl].ended || !stream[kImpl].ending || stream[kImpl].flushing) {
4551
+ function end(stream2) {
4552
+ if (stream2[kImpl].ended || !stream2[kImpl].ending || stream2[kImpl].flushing) {
4553
4553
  return;
4554
4554
  }
4555
- stream[kImpl].ended = true;
4555
+ stream2[kImpl].ended = true;
4556
4556
  try {
4557
- stream.flushSync();
4558
- let readIndex = Atomics.load(stream[kImpl].state, READ_INDEX);
4559
- Atomics.store(stream[kImpl].state, WRITE_INDEX, -1);
4560
- Atomics.notify(stream[kImpl].state, WRITE_INDEX);
4557
+ stream2.flushSync();
4558
+ let readIndex = Atomics.load(stream2[kImpl].state, READ_INDEX);
4559
+ Atomics.store(stream2[kImpl].state, WRITE_INDEX, -1);
4560
+ Atomics.notify(stream2[kImpl].state, WRITE_INDEX);
4561
4561
  let spins = 0;
4562
4562
  while (readIndex !== -1) {
4563
- Atomics.wait(stream[kImpl].state, READ_INDEX, readIndex, 1e3);
4564
- readIndex = Atomics.load(stream[kImpl].state, READ_INDEX);
4563
+ Atomics.wait(stream2[kImpl].state, READ_INDEX, readIndex, 1e3);
4564
+ readIndex = Atomics.load(stream2[kImpl].state, READ_INDEX);
4565
4565
  if (readIndex === -2) {
4566
- destroy(stream, new Error("end() failed"));
4566
+ destroy(stream2, new Error("end() failed"));
4567
4567
  return;
4568
4568
  }
4569
4569
  if (++spins === 10) {
4570
- destroy(stream, new Error("end() took too long (10s)"));
4570
+ destroy(stream2, new Error("end() took too long (10s)"));
4571
4571
  return;
4572
4572
  }
4573
4573
  }
4574
4574
  process.nextTick(() => {
4575
- stream[kImpl].finished = true;
4576
- stream.emit("finish");
4575
+ stream2[kImpl].finished = true;
4576
+ stream2.emit("finish");
4577
4577
  });
4578
4578
  } catch (err) {
4579
- destroy(stream, err);
4579
+ destroy(stream2, err);
4580
4580
  }
4581
4581
  }
4582
- function writeSync(stream) {
4582
+ function writeSync(stream2) {
4583
4583
  const cb = () => {
4584
- if (stream[kImpl].ending) {
4585
- end(stream);
4586
- } else if (stream[kImpl].needDrain) {
4587
- process.nextTick(drain, stream);
4584
+ if (stream2[kImpl].ending) {
4585
+ end(stream2);
4586
+ } else if (stream2[kImpl].needDrain) {
4587
+ process.nextTick(drain, stream2);
4588
4588
  }
4589
4589
  };
4590
- stream[kImpl].flushing = false;
4591
- while (stream[kImpl].buf.length !== 0) {
4592
- const writeIndex = Atomics.load(stream[kImpl].state, WRITE_INDEX);
4593
- let leftover = stream[kImpl].data.length - writeIndex;
4590
+ stream2[kImpl].flushing = false;
4591
+ while (stream2[kImpl].buf.length !== 0) {
4592
+ const writeIndex = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
4593
+ let leftover = stream2[kImpl].data.length - writeIndex;
4594
4594
  if (leftover === 0) {
4595
- flushSync(stream);
4596
- Atomics.store(stream[kImpl].state, READ_INDEX, 0);
4597
- Atomics.store(stream[kImpl].state, WRITE_INDEX, 0);
4598
- Atomics.notify(stream[kImpl].state, READ_INDEX);
4595
+ flushSync(stream2);
4596
+ Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
4597
+ Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
4598
+ Atomics.notify(stream2[kImpl].state, READ_INDEX);
4599
4599
  continue;
4600
4600
  } else if (leftover < 0) {
4601
4601
  throw new Error("overwritten");
4602
4602
  }
4603
- let toWrite = stream[kImpl].buf.slice(0, leftover);
4603
+ let toWrite = stream2[kImpl].buf.slice(0, leftover);
4604
4604
  let toWriteBytes = Buffer.byteLength(toWrite);
4605
4605
  if (toWriteBytes <= leftover) {
4606
- stream[kImpl].buf = stream[kImpl].buf.slice(leftover);
4607
- write(stream, toWrite, cb);
4606
+ stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
4607
+ write(stream2, toWrite, cb);
4608
4608
  } else {
4609
- flushSync(stream);
4610
- Atomics.store(stream[kImpl].state, READ_INDEX, 0);
4611
- Atomics.store(stream[kImpl].state, WRITE_INDEX, 0);
4612
- Atomics.notify(stream[kImpl].state, READ_INDEX);
4613
- while (toWriteBytes > stream[kImpl].buf.length) {
4609
+ flushSync(stream2);
4610
+ Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
4611
+ Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
4612
+ Atomics.notify(stream2[kImpl].state, READ_INDEX);
4613
+ while (toWriteBytes > stream2[kImpl].buf.length) {
4614
4614
  leftover = leftover / 2;
4615
- toWrite = stream[kImpl].buf.slice(0, leftover);
4615
+ toWrite = stream2[kImpl].buf.slice(0, leftover);
4616
4616
  toWriteBytes = Buffer.byteLength(toWrite);
4617
4617
  }
4618
- stream[kImpl].buf = stream[kImpl].buf.slice(leftover);
4619
- write(stream, toWrite, cb);
4618
+ stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
4619
+ write(stream2, toWrite, cb);
4620
4620
  }
4621
4621
  }
4622
4622
  }
4623
- function flushSync(stream) {
4624
- if (stream[kImpl].flushing) {
4623
+ function flushSync(stream2) {
4624
+ if (stream2[kImpl].flushing) {
4625
4625
  throw new Error("unable to flush while flushing");
4626
4626
  }
4627
- const writeIndex = Atomics.load(stream[kImpl].state, WRITE_INDEX);
4627
+ const writeIndex = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
4628
4628
  let spins = 0;
4629
4629
  while (true) {
4630
- const readIndex = Atomics.load(stream[kImpl].state, READ_INDEX);
4630
+ const readIndex = Atomics.load(stream2[kImpl].state, READ_INDEX);
4631
4631
  if (readIndex === -2) {
4632
4632
  throw Error("_flushSync failed");
4633
4633
  }
4634
4634
  if (readIndex !== writeIndex) {
4635
- Atomics.wait(stream[kImpl].state, READ_INDEX, readIndex, 1e3);
4635
+ Atomics.wait(stream2[kImpl].state, READ_INDEX, readIndex, 1e3);
4636
4636
  } else {
4637
4637
  break;
4638
4638
  }
@@ -4657,11 +4657,11 @@ var require_transport = __commonJS({
4657
4657
  var sleep = require_atomic_sleep();
4658
4658
  var onExit = require_on_exit_leak_free();
4659
4659
  var ThreadStream = require_thread_stream();
4660
- function setupOnExit(stream) {
4661
- onExit.register(stream, autoEnd);
4662
- onExit.registerBeforeExit(stream, flush);
4663
- stream.on("close", function() {
4664
- onExit.unregister(stream);
4660
+ function setupOnExit(stream2) {
4661
+ onExit.register(stream2, autoEnd);
4662
+ onExit.registerBeforeExit(stream2, flush);
4663
+ stream2.on("close", function() {
4664
+ onExit.unregister(stream2);
4665
4665
  });
4666
4666
  }
4667
4667
  function hasPreloadFlags() {
@@ -4754,44 +4754,44 @@ var require_transport = __commonJS({
4754
4754
  }
4755
4755
  }
4756
4756
  workerOpts = { ...workerOpts, name };
4757
- const stream = new ThreadStream({
4757
+ const stream2 = new ThreadStream({
4758
4758
  filename,
4759
4759
  workerData,
4760
4760
  workerOpts,
4761
4761
  sync
4762
4762
  });
4763
- stream.on("ready", onReady);
4764
- stream.on("close", function() {
4763
+ stream2.on("ready", onReady);
4764
+ stream2.on("close", function() {
4765
4765
  process.removeListener("exit", onExit2);
4766
4766
  });
4767
4767
  process.on("exit", onExit2);
4768
4768
  function onReady() {
4769
4769
  process.removeListener("exit", onExit2);
4770
- stream.unref();
4770
+ stream2.unref();
4771
4771
  if (workerOpts.autoEnd !== false) {
4772
- setupOnExit(stream);
4772
+ setupOnExit(stream2);
4773
4773
  }
4774
4774
  }
4775
4775
  function onExit2() {
4776
- if (stream.closed) {
4776
+ if (stream2.closed) {
4777
4777
  return;
4778
4778
  }
4779
- stream.flushSync();
4779
+ stream2.flushSync();
4780
4780
  sleep(100);
4781
- stream.end();
4781
+ stream2.end();
4782
4782
  }
4783
- return stream;
4783
+ return stream2;
4784
4784
  }
4785
- function autoEnd(stream) {
4786
- stream.ref();
4787
- stream.flushSync();
4788
- stream.end();
4789
- stream.once("close", function() {
4790
- stream.unref();
4785
+ function autoEnd(stream2) {
4786
+ stream2.ref();
4787
+ stream2.flushSync();
4788
+ stream2.end();
4789
+ stream2.once("close", function() {
4790
+ stream2.unref();
4791
4791
  });
4792
4792
  }
4793
- function flush(stream) {
4794
- stream.flushSync();
4793
+ function flush(stream2) {
4794
+ stream2.flushSync();
4795
4795
  }
4796
4796
  function transport(fullOptions) {
4797
4797
  const { pipeline, targets, levels, dedupe, worker = {}, caller = getCallers(), sync = false } = fullOptions;
@@ -5049,15 +5049,15 @@ var require_tools = __commonJS({
5049
5049
  return data + propStr + msgStr + end;
5050
5050
  }
5051
5051
  }
5052
- function asChindings(instance, bindings) {
5052
+ function asChindings(instance2, bindings) {
5053
5053
  let value;
5054
- let data = instance[chindingsSym];
5055
- const stringify2 = instance[stringifySym];
5056
- const stringifySafe = instance[stringifySafeSym];
5057
- const stringifiers = instance[stringifiersSym];
5054
+ let data = instance2[chindingsSym];
5055
+ const stringify2 = instance2[stringifySym];
5056
+ const stringifySafe = instance2[stringifySafeSym];
5057
+ const stringifiers = instance2[stringifiersSym];
5058
5058
  const wildcardStringifier = stringifiers[wildcardFirstSym];
5059
- const serializers = instance[serializersSym];
5060
- const formatter = instance[formattersSym].bindings;
5059
+ const serializers = instance2[serializersSym];
5060
+ const formatter = instance2[formattersSym].bindings;
5061
5061
  bindings = formatter(bindings);
5062
5062
  for (const key in bindings) {
5063
5063
  value = bindings[key];
@@ -5071,56 +5071,56 @@ var require_tools = __commonJS({
5071
5071
  }
5072
5072
  return data;
5073
5073
  }
5074
- function hasBeenTampered(stream) {
5075
- return stream.write !== stream.constructor.prototype.write;
5074
+ function hasBeenTampered(stream2) {
5075
+ return stream2.write !== stream2.constructor.prototype.write;
5076
5076
  }
5077
5077
  function buildSafeSonicBoom(opts) {
5078
- const stream = new SonicBoom(opts);
5079
- stream.on("error", filterBrokenPipe);
5078
+ const stream2 = new SonicBoom(opts);
5079
+ stream2.on("error", filterBrokenPipe);
5080
5080
  if (!opts.sync && isMainThread) {
5081
- onExit.register(stream, autoEnd);
5082
- stream.on("close", function() {
5083
- onExit.unregister(stream);
5081
+ onExit.register(stream2, autoEnd);
5082
+ stream2.on("close", function() {
5083
+ onExit.unregister(stream2);
5084
5084
  });
5085
5085
  }
5086
- return stream;
5086
+ return stream2;
5087
5087
  function filterBrokenPipe(err) {
5088
5088
  if (err.code === "EPIPE") {
5089
- stream.write = noop;
5090
- stream.end = noop;
5091
- stream.flushSync = noop;
5092
- stream.destroy = noop;
5089
+ stream2.write = noop;
5090
+ stream2.end = noop;
5091
+ stream2.flushSync = noop;
5092
+ stream2.destroy = noop;
5093
5093
  return;
5094
5094
  }
5095
- stream.removeListener("error", filterBrokenPipe);
5096
- stream.emit("error", err);
5095
+ stream2.removeListener("error", filterBrokenPipe);
5096
+ stream2.emit("error", err);
5097
5097
  }
5098
5098
  }
5099
- function autoEnd(stream, eventName) {
5100
- if (stream.destroyed) {
5099
+ function autoEnd(stream2, eventName) {
5100
+ if (stream2.destroyed) {
5101
5101
  return;
5102
5102
  }
5103
5103
  if (eventName === "beforeExit") {
5104
- stream.flush();
5105
- stream.on("drain", function() {
5106
- stream.end();
5104
+ stream2.flush();
5105
+ stream2.on("drain", function() {
5106
+ stream2.end();
5107
5107
  });
5108
5108
  } else {
5109
- stream.flushSync();
5109
+ stream2.flushSync();
5110
5110
  }
5111
5111
  }
5112
5112
  function createArgsNormalizer(defaultOptions) {
5113
- return function normalizeArgs(instance, caller, opts = {}, stream) {
5113
+ return function normalizeArgs(instance2, caller, opts = {}, stream2) {
5114
5114
  if (typeof opts === "string") {
5115
- stream = buildSafeSonicBoom({ dest: opts });
5115
+ stream2 = buildSafeSonicBoom({ dest: opts });
5116
5116
  opts = {};
5117
- } else if (typeof stream === "string") {
5117
+ } else if (typeof stream2 === "string") {
5118
5118
  if (opts && opts.transport) {
5119
5119
  throw Error("only one of option.transport or stream can be specified");
5120
5120
  }
5121
- stream = buildSafeSonicBoom({ dest: stream });
5121
+ stream2 = buildSafeSonicBoom({ dest: stream2 });
5122
5122
  } else if (opts instanceof SonicBoom || opts.writable || opts._writableState) {
5123
- stream = opts;
5123
+ stream2 = opts;
5124
5124
  opts = {};
5125
5125
  } else if (opts.transport) {
5126
5126
  if (opts.transport instanceof SonicBoom || opts.transport.writable || opts.transport._writableState) {
@@ -5133,7 +5133,7 @@ var require_tools = __commonJS({
5133
5133
  if (opts.customLevels) {
5134
5134
  customLevels = opts.useOnlyCustomLevels ? opts.customLevels : Object.assign({}, opts.levels, opts.customLevels);
5135
5135
  }
5136
- stream = transport({ caller, ...opts.transport, levels: customLevels });
5136
+ stream2 = transport({ caller, ...opts.transport, levels: customLevels });
5137
5137
  }
5138
5138
  opts = Object.assign({}, defaultOptions, opts);
5139
5139
  opts.serializers = Object.assign({}, defaultOptions.serializers, opts.serializers);
@@ -5144,14 +5144,14 @@ var require_tools = __commonJS({
5144
5144
  const { enabled, onChild } = opts;
5145
5145
  if (enabled === false) opts.level = "silent";
5146
5146
  if (!onChild) opts.onChild = noop;
5147
- if (!stream) {
5147
+ if (!stream2) {
5148
5148
  if (!hasBeenTampered(process.stdout)) {
5149
- stream = buildSafeSonicBoom({ fd: process.stdout.fd || 1 });
5149
+ stream2 = buildSafeSonicBoom({ fd: process.stdout.fd || 1 });
5150
5150
  } else {
5151
- stream = process.stdout;
5151
+ stream2 = process.stdout;
5152
5152
  }
5153
5153
  }
5154
- return { opts, stream };
5154
+ return { opts, stream: stream2 };
5155
5155
  };
5156
5156
  }
5157
5157
  function stringify(obj, stringifySafeFn) {
@@ -5238,11 +5238,11 @@ var require_levels = __commonJS({
5238
5238
  fatal: (hook) => {
5239
5239
  const logFatal = genLog(DEFAULT_LEVELS.fatal, hook);
5240
5240
  return function(...args) {
5241
- const stream = this[streamSym];
5241
+ const stream2 = this[streamSym];
5242
5242
  logFatal.call(this, ...args);
5243
- if (typeof stream.flushSync === "function") {
5243
+ if (typeof stream2.flushSync === "function") {
5244
5244
  try {
5245
- stream.flushSync();
5245
+ stream2.flushSync();
5246
5246
  } catch (e) {
5247
5247
  }
5248
5248
  }
@@ -5262,16 +5262,16 @@ var require_levels = __commonJS({
5262
5262
  o[k] = '{"level":' + Number(k);
5263
5263
  return o;
5264
5264
  }, {});
5265
- function genLsCache(instance) {
5266
- const formatter = instance[formattersSym].level;
5267
- const { labels } = instance.levels;
5265
+ function genLsCache(instance2) {
5266
+ const formatter = instance2[formattersSym].level;
5267
+ const { labels } = instance2.levels;
5268
5268
  const cache = {};
5269
5269
  for (const label in labels) {
5270
5270
  const level2 = formatter(labels[label], Number(label));
5271
5271
  cache[label] = JSON.stringify(level2).slice(0, -1);
5272
5272
  }
5273
- instance[lsCacheSym] = cache;
5274
- return instance;
5273
+ instance2[lsCacheSym] = cache;
5274
+ return instance2;
5275
5275
  }
5276
5276
  function isStandardLevel(level2, useOnlyCustomLevels) {
5277
5277
  if (useOnlyCustomLevels) {
@@ -5424,7 +5424,7 @@ var require_meta = __commonJS({
5424
5424
  var require_proto = __commonJS({
5425
5425
  "node_modules/pino/lib/proto.js"(exports, module) {
5426
5426
  "use strict";
5427
- var { EventEmitter: EventEmitter6 } = __require("node:events");
5427
+ var { EventEmitter: EventEmitter7 } = __require("node:events");
5428
5428
  var {
5429
5429
  lsCacheSym,
5430
5430
  levelValSym,
@@ -5505,7 +5505,7 @@ var require_proto = __commonJS({
5505
5505
  [getLevelSym]: getLevel,
5506
5506
  [setLevelSym]: setLevel
5507
5507
  };
5508
- Object.setPrototypeOf(prototype, EventEmitter6.prototype);
5508
+ Object.setPrototypeOf(prototype, EventEmitter7.prototype);
5509
5509
  module.exports = function() {
5510
5510
  return Object.create(prototype);
5511
5511
  };
@@ -5516,49 +5516,49 @@ var require_proto = __commonJS({
5516
5516
  }
5517
5517
  const serializers = this[serializersSym];
5518
5518
  const formatters = this[formattersSym];
5519
- const instance = Object.create(this);
5519
+ const instance2 = Object.create(this);
5520
5520
  if (options == null) {
5521
- if (instance[formattersSym].bindings !== resetChildingsFormatter) {
5522
- instance[formattersSym] = buildFormatters(
5521
+ if (instance2[formattersSym].bindings !== resetChildingsFormatter) {
5522
+ instance2[formattersSym] = buildFormatters(
5523
5523
  formatters.level,
5524
5524
  resetChildingsFormatter,
5525
5525
  formatters.log
5526
5526
  );
5527
5527
  }
5528
- instance[chindingsSym] = asChindings(instance, bindings2);
5528
+ instance2[chindingsSym] = asChindings(instance2, bindings2);
5529
5529
  if (this.onChild !== noop) {
5530
- this.onChild(instance);
5530
+ this.onChild(instance2);
5531
5531
  }
5532
- return instance;
5532
+ return instance2;
5533
5533
  }
5534
5534
  if (options.hasOwnProperty("serializers") === true) {
5535
- instance[serializersSym] = /* @__PURE__ */ Object.create(null);
5535
+ instance2[serializersSym] = /* @__PURE__ */ Object.create(null);
5536
5536
  for (const k in serializers) {
5537
- instance[serializersSym][k] = serializers[k];
5537
+ instance2[serializersSym][k] = serializers[k];
5538
5538
  }
5539
5539
  const parentSymbols = Object.getOwnPropertySymbols(serializers);
5540
5540
  for (var i = 0; i < parentSymbols.length; i++) {
5541
5541
  const ks = parentSymbols[i];
5542
- instance[serializersSym][ks] = serializers[ks];
5542
+ instance2[serializersSym][ks] = serializers[ks];
5543
5543
  }
5544
5544
  for (const bk in options.serializers) {
5545
- instance[serializersSym][bk] = options.serializers[bk];
5545
+ instance2[serializersSym][bk] = options.serializers[bk];
5546
5546
  }
5547
5547
  const bindingsSymbols = Object.getOwnPropertySymbols(options.serializers);
5548
5548
  for (var bi = 0; bi < bindingsSymbols.length; bi++) {
5549
5549
  const bks = bindingsSymbols[bi];
5550
- instance[serializersSym][bks] = options.serializers[bks];
5550
+ instance2[serializersSym][bks] = options.serializers[bks];
5551
5551
  }
5552
- } else instance[serializersSym] = serializers;
5552
+ } else instance2[serializersSym] = serializers;
5553
5553
  if (options.hasOwnProperty("formatters")) {
5554
5554
  const { level: level2, bindings: chindings, log } = options.formatters;
5555
- instance[formattersSym] = buildFormatters(
5555
+ instance2[formattersSym] = buildFormatters(
5556
5556
  level2 || formatters.level,
5557
5557
  chindings || resetChildingsFormatter,
5558
5558
  log || formatters.log
5559
5559
  );
5560
5560
  } else {
5561
- instance[formattersSym] = buildFormatters(
5561
+ instance2[formattersSym] = buildFormatters(
5562
5562
  formatters.level,
5563
5563
  resetChildingsFormatter,
5564
5564
  formatters.log
@@ -5566,27 +5566,27 @@ var require_proto = __commonJS({
5566
5566
  }
5567
5567
  if (options.hasOwnProperty("customLevels") === true) {
5568
5568
  assertNoLevelCollisions(this.levels, options.customLevels);
5569
- instance.levels = mappings(options.customLevels, instance[useOnlyCustomLevelsSym]);
5570
- genLsCache(instance);
5569
+ instance2.levels = mappings(options.customLevels, instance2[useOnlyCustomLevelsSym]);
5570
+ genLsCache(instance2);
5571
5571
  }
5572
5572
  if (typeof options.redact === "object" && options.redact !== null || Array.isArray(options.redact)) {
5573
- instance.redact = options.redact;
5574
- const stringifiers = redaction(instance.redact, stringify);
5573
+ instance2.redact = options.redact;
5574
+ const stringifiers = redaction(instance2.redact, stringify);
5575
5575
  const formatOpts = { stringify: stringifiers[redactFmtSym] };
5576
- instance[stringifySym] = stringify;
5577
- instance[stringifiersSym] = stringifiers;
5578
- instance[formatOptsSym] = formatOpts;
5576
+ instance2[stringifySym] = stringify;
5577
+ instance2[stringifiersSym] = stringifiers;
5578
+ instance2[formatOptsSym] = formatOpts;
5579
5579
  }
5580
5580
  if (typeof options.msgPrefix === "string") {
5581
- instance[msgPrefixSym] = (this[msgPrefixSym] || "") + options.msgPrefix;
5581
+ instance2[msgPrefixSym] = (this[msgPrefixSym] || "") + options.msgPrefix;
5582
5582
  }
5583
- instance[chindingsSym] = asChindings(instance, bindings2);
5583
+ instance2[chindingsSym] = asChindings(instance2, bindings2);
5584
5584
  if (options.level !== void 0 && options.level !== this.level || options.hasOwnProperty("customLevels")) {
5585
5585
  const childLevel = options.level || this.level;
5586
- instance[setLevelSym](childLevel);
5586
+ instance2[setLevelSym](childLevel);
5587
5587
  }
5588
- this.onChild(instance);
5589
- return instance;
5588
+ this.onChild(instance2);
5589
+ return instance2;
5590
5590
  }
5591
5591
  function bindings() {
5592
5592
  const chindings = this[chindingsSym];
@@ -5628,23 +5628,23 @@ var require_proto = __commonJS({
5628
5628
  obj = mixinMergeStrategy(obj, mixin(obj, num, this));
5629
5629
  }
5630
5630
  const s = this[asJsonSym](obj, msg, num, t);
5631
- const stream = this[streamSym];
5632
- if (stream[needsMetadataGsym] === true) {
5633
- stream.lastLevel = num;
5634
- stream.lastObj = obj;
5635
- stream.lastMsg = msg;
5636
- stream.lastTime = t.slice(this[timeSliceIndexSym]);
5637
- stream.lastLogger = this;
5631
+ const stream2 = this[streamSym];
5632
+ if (stream2[needsMetadataGsym] === true) {
5633
+ stream2.lastLevel = num;
5634
+ stream2.lastObj = obj;
5635
+ stream2.lastMsg = msg;
5636
+ stream2.lastTime = t.slice(this[timeSliceIndexSym]);
5637
+ stream2.lastLogger = this;
5638
5638
  }
5639
- stream.write(streamWriteHook ? streamWriteHook(s) : s);
5639
+ stream2.write(streamWriteHook ? streamWriteHook(s) : s);
5640
5640
  }
5641
5641
  function flush(cb) {
5642
5642
  if (cb != null && typeof cb !== "function") {
5643
5643
  throw Error("callback must be a function");
5644
5644
  }
5645
- const stream = this[streamSym];
5646
- if (typeof stream.flush === "function") {
5647
- stream.flush(cb || noop);
5645
+ const stream2 = this[streamSym];
5646
+ if (typeof stream2.flush === "function") {
5647
+ stream2.flush(cb || noop);
5648
5648
  } else if (cb) cb();
5649
5649
  }
5650
5650
  }
@@ -6289,23 +6289,23 @@ var require_multistream = __commonJS({
6289
6289
  const level2 = this.lastLevel;
6290
6290
  const { streams: streams2 } = this;
6291
6291
  let recordedLevel = 0;
6292
- let stream;
6292
+ let stream2;
6293
6293
  for (let i = initLoopVar(streams2.length, opts.dedupe); checkLoopVar(i, streams2.length, opts.dedupe); i = adjustLoopVar(i, opts.dedupe)) {
6294
6294
  dest = streams2[i];
6295
6295
  if (dest.level <= level2) {
6296
6296
  if (recordedLevel !== 0 && recordedLevel !== dest.level) {
6297
6297
  break;
6298
6298
  }
6299
- stream = dest.stream;
6300
- if (stream[metadata]) {
6299
+ stream2 = dest.stream;
6300
+ if (stream2[metadata]) {
6301
6301
  const { lastTime, lastMsg, lastObj, lastLogger } = this;
6302
- stream.lastLevel = level2;
6303
- stream.lastTime = lastTime;
6304
- stream.lastMsg = lastMsg;
6305
- stream.lastObj = lastObj;
6306
- stream.lastLogger = lastLogger;
6302
+ stream2.lastLevel = level2;
6303
+ stream2.lastTime = lastTime;
6304
+ stream2.lastMsg = lastMsg;
6305
+ stream2.lastObj = lastObj;
6306
+ stream2.lastLogger = lastLogger;
6307
6307
  }
6308
- stream.write(data);
6308
+ stream2.write(data);
6309
6309
  if (opts.dedupe) {
6310
6310
  recordedLevel = dest.level;
6311
6311
  }
@@ -6315,16 +6315,16 @@ var require_multistream = __commonJS({
6315
6315
  }
6316
6316
  }
6317
6317
  function emit(...args) {
6318
- for (const { stream } of this.streams) {
6319
- if (typeof stream.emit === "function") {
6320
- stream.emit(...args);
6318
+ for (const { stream: stream2 } of this.streams) {
6319
+ if (typeof stream2.emit === "function") {
6320
+ stream2.emit(...args);
6321
6321
  }
6322
6322
  }
6323
6323
  }
6324
6324
  function flushSync() {
6325
- for (const { stream } of this.streams) {
6326
- if (typeof stream.flushSync === "function") {
6327
- stream.flushSync();
6325
+ for (const { stream: stream2 } of this.streams) {
6326
+ if (typeof stream2.flushSync === "function") {
6327
+ stream2.flushSync();
6328
6328
  }
6329
6329
  }
6330
6330
  }
@@ -6370,11 +6370,11 @@ var require_multistream = __commonJS({
6370
6370
  return res;
6371
6371
  }
6372
6372
  function end() {
6373
- for (const { stream } of this.streams) {
6374
- if (typeof stream.flushSync === "function") {
6375
- stream.flushSync();
6373
+ for (const { stream: stream2 } of this.streams) {
6374
+ if (typeof stream2.flushSync === "function") {
6375
+ stream2.flushSync();
6376
6376
  }
6377
- stream.end();
6377
+ stream2.end();
6378
6378
  }
6379
6379
  }
6380
6380
  function clone(level2) {
@@ -6502,8 +6502,8 @@ var require_pino = __commonJS({
6502
6502
  var normalize = createArgsNormalizer(defaultOptions);
6503
6503
  var serializers = Object.assign(/* @__PURE__ */ Object.create(null), stdSerializers);
6504
6504
  function pino2(...args) {
6505
- const instance = {};
6506
- const { opts, stream } = normalize(instance, caller(), ...args);
6505
+ const instance2 = {};
6506
+ const { opts, stream: stream2 } = normalize(instance2, caller(), ...args);
6507
6507
  if (opts.level && typeof opts.level === "string" && DEFAULT_LEVELS[opts.level.toLowerCase()] !== void 0) opts.level = opts.level.toLowerCase();
6508
6508
  const {
6509
6509
  redact,
@@ -6566,16 +6566,16 @@ var require_pino = __commonJS({
6566
6566
  if (msgPrefix && typeof msgPrefix !== "string") throw Error(`Unknown msgPrefix type "${typeof msgPrefix}" - expected "string"`);
6567
6567
  assertDefaultLevelFound(level2, customLevels, useOnlyCustomLevels);
6568
6568
  const levels = mappings(customLevels, useOnlyCustomLevels);
6569
- if (typeof stream.emit === "function") {
6570
- stream.emit("message", { code: "PINO_CONFIG", config: { levels, messageKey, errorKey } });
6569
+ if (typeof stream2.emit === "function") {
6570
+ stream2.emit("message", { code: "PINO_CONFIG", config: { levels, messageKey, errorKey } });
6571
6571
  }
6572
6572
  assertLevelComparison(levelComparison);
6573
6573
  const levelCompFunc = genLevelComparison(levelComparison);
6574
- Object.assign(instance, {
6574
+ Object.assign(instance2, {
6575
6575
  levels,
6576
6576
  [levelCompSym]: levelCompFunc,
6577
6577
  [useOnlyCustomLevelsSym]: useOnlyCustomLevels,
6578
- [streamSym]: stream,
6578
+ [streamSym]: stream2,
6579
6579
  [timeSym]: time2,
6580
6580
  [timeSliceIndexSym]: timeSliceIndex,
6581
6581
  [stringifySym]: stringify,
@@ -6598,10 +6598,10 @@ var require_pino = __commonJS({
6598
6598
  onChild,
6599
6599
  [msgPrefixSym]: msgPrefix
6600
6600
  });
6601
- Object.setPrototypeOf(instance, proto());
6602
- genLsCache(instance);
6603
- instance[setLevelSym](level2);
6604
- return instance;
6601
+ Object.setPrototypeOf(instance2, proto());
6602
+ genLsCache(instance2);
6603
+ instance2[setLevelSym](level2);
6604
+ return instance2;
6605
6605
  }
6606
6606
  module.exports = pino2;
6607
6607
  module.exports.destination = (dest = process.stdout.fd) => {
@@ -6738,7 +6738,7 @@ import { EventEmitter } from "events";
6738
6738
  import fs from "fs";
6739
6739
  import { createWriteStream } from "fs";
6740
6740
  import { tmpdir as tmpdir4 } from "os";
6741
- import { join as join4 } from "path";
6741
+ import { join as join5 } from "path";
6742
6742
 
6743
6743
  // src/core/backends/naudiodon-backend.ts
6744
6744
  var UnsupportedError = class extends Error {
@@ -7389,12 +7389,43 @@ var HowlerBackend = class {
7389
7389
  }
7390
7390
  };
7391
7391
 
7392
+ // src/utils/logger.ts
7393
+ var import_pino = __toESM(require_pino(), 1);
7394
+ import { homedir } from "os";
7395
+ import { join as join4 } from "path";
7396
+ import { existsSync as existsSync4, mkdirSync } from "fs";
7397
+ var logDir = join4(homedir(), ".ocosay");
7398
+ var logFile = join4(logDir, "ocosay.log");
7399
+ if (!existsSync4(logDir)) {
7400
+ try {
7401
+ mkdirSync(logDir, { recursive: true });
7402
+ } catch {
7403
+ }
7404
+ }
7405
+ var streams = [
7406
+ { stream: process.stdout }
7407
+ ];
7408
+ try {
7409
+ streams.push({ stream: import_pino.default.destination({ dest: logFile, mkdir: true }) });
7410
+ } catch {
7411
+ }
7412
+ var level = process.env.NODE_ENV !== "production" ? "debug" : process.env.OCOSAY_LOG_LEVEL || "info";
7413
+ var logger = (0, import_pino.default)(
7414
+ {
7415
+ level,
7416
+ base: { service: "ocosay" },
7417
+ timestamp: import_pino.default.stdTimeFunctions.isoTime
7418
+ },
7419
+ import_pino.default.multistream(streams)
7420
+ );
7421
+
7392
7422
  // src/core/backends/index.ts
7393
7423
  function isNaudiodonAvailable() {
7394
7424
  try {
7395
7425
  __require.resolve("naudiodon");
7396
7426
  return true;
7397
- } catch (e) {
7427
+ } catch (err) {
7428
+ logger.debug({ err }, "naudiodon not available");
7398
7429
  return false;
7399
7430
  }
7400
7431
  }
@@ -7417,7 +7448,8 @@ function createBackend(type = "auto" /* AUTO */, options = {}) {
7417
7448
  if (naudiodon) {
7418
7449
  return new NaudiodonBackend(options);
7419
7450
  }
7420
- } catch (e) {
7451
+ } catch (err) {
7452
+ logger.warn({ err }, "failed to initialize naudiodon backend");
7421
7453
  }
7422
7454
  }
7423
7455
  switch (platform) {
@@ -7510,7 +7542,7 @@ var AudioPlayer = class extends EventEmitter {
7510
7542
  this._playing = true;
7511
7543
  this._paused = false;
7512
7544
  try {
7513
- const tempFile = join4(tmpdir4(), `ocosay-${Date.now()}.${format}`);
7545
+ const tempFile = join5(tmpdir4(), `ocosay-${Date.now()}.${format}`);
7514
7546
  this.currentFile = tempFile;
7515
7547
  if (Buffer.isBuffer(audioData)) {
7516
7548
  fs.writeFileSync(tempFile, audioData);
@@ -7607,42 +7639,12 @@ var AudioPlayer = class extends EventEmitter {
7607
7639
  }
7608
7640
  };
7609
7641
 
7610
- // src/utils/logger.ts
7611
- var import_pino = __toESM(require_pino(), 1);
7612
- import { homedir } from "os";
7613
- import { join as join5 } from "path";
7614
- import { existsSync as existsSync4, mkdirSync } from "fs";
7615
- var logDir = join5(homedir(), ".ocosay");
7616
- var logFile = join5(logDir, "ocosay.log");
7617
- if (!existsSync4(logDir)) {
7618
- try {
7619
- mkdirSync(logDir, { recursive: true });
7620
- } catch {
7621
- }
7622
- }
7623
- var streams = [
7624
- { stream: process.stdout }
7625
- ];
7626
- try {
7627
- streams.push({ stream: import_pino.default.destination({ dest: logFile, mkdir: true }) });
7628
- } catch {
7629
- }
7630
- var level = process.env.NODE_ENV !== "production" ? "debug" : process.env.OCOSAY_LOG_LEVEL || "info";
7631
- var logger = (0, import_pino.default)(
7632
- {
7633
- level,
7634
- base: { service: "ocosay" },
7635
- timestamp: import_pino.default.stdTimeFunctions.isoTime
7636
- },
7637
- import_pino.default.multistream(streams)
7638
- );
7639
-
7640
7642
  // src/core/speaker.ts
7641
7643
  function toast(options) {
7642
- const tui = global.__opencode_tui__;
7643
- if (tui?.showToast) {
7644
+ const tui2 = global.__opencode_tui__;
7645
+ if (tui2?.showToast) {
7644
7646
  try {
7645
- tui.showToast({
7647
+ tui2.showToast({
7646
7648
  title: options.title,
7647
7649
  message: options.body,
7648
7650
  variant: options.type,
@@ -7733,6 +7735,7 @@ var Speaker = class extends EventEmitter2 {
7733
7735
  }
7734
7736
  } catch (error) {
7735
7737
  this.isSpeaking = false;
7738
+ logger.error({ error }, "speak failed");
7736
7739
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
7737
7740
  toast({
7738
7741
  title: "TTS playback error",
@@ -7809,50 +7812,512 @@ var Speaker = class extends EventEmitter2 {
7809
7812
  return provider.getCapabilities();
7810
7813
  }
7811
7814
  /**
7812
- * 获取所有已注册的 Provider
7815
+ * 获取所有已注册的 Provider
7816
+ */
7817
+ getProviders() {
7818
+ return listProviders();
7819
+ }
7820
+ /**
7821
+ * 是否正在播放
7822
+ */
7823
+ isPlaying() {
7824
+ return this.isSpeaking && !this.isPaused;
7825
+ }
7826
+ /**
7827
+ * 是否暂停
7828
+ */
7829
+ isPausedState() {
7830
+ return this.isPaused;
7831
+ }
7832
+ };
7833
+ var defaultSpeaker;
7834
+ function getDefaultSpeaker() {
7835
+ if (!defaultSpeaker) {
7836
+ defaultSpeaker = new Speaker();
7837
+ }
7838
+ return defaultSpeaker;
7839
+ }
7840
+ async function speak(text, options) {
7841
+ const speaker2 = getDefaultSpeaker();
7842
+ return speaker2.speak(text, options);
7843
+ }
7844
+ async function stop() {
7845
+ const speaker2 = getDefaultSpeaker();
7846
+ return speaker2.stop();
7847
+ }
7848
+ function pause() {
7849
+ const speaker2 = getDefaultSpeaker();
7850
+ speaker2.pause();
7851
+ }
7852
+ function resume() {
7853
+ const speaker2 = getDefaultSpeaker();
7854
+ speaker2.resume();
7855
+ }
7856
+ async function listVoices(providerName) {
7857
+ const speaker2 = getDefaultSpeaker();
7858
+ return speaker2.listVoices(providerName);
7859
+ }
7860
+
7861
+ // src/services/speaker-service.ts
7862
+ var SpeakerService = class {
7863
+ constructor(options = {}) {
7864
+ this.options = options;
7865
+ this.speaker = getDefaultSpeaker();
7866
+ }
7867
+ options;
7868
+ speaker;
7869
+ async speak(text, options) {
7870
+ const timestamp = this.getTimestamp();
7871
+ logger.info(`[Ocosay][${timestamp}][INFO][Speaker] \u5BF9\u5E94\u4E8B\u4EF6{\u64AD\u653E\u5F00\u59CB} - \u6587\u672C\u957F\u5EA6: ${text.length}`);
7872
+ return this.speaker.speak(text, options);
7873
+ }
7874
+ pause() {
7875
+ this.speaker.pause();
7876
+ }
7877
+ resume() {
7878
+ this.speaker.resume();
7879
+ }
7880
+ async stop() {
7881
+ return this.speaker.stop();
7882
+ }
7883
+ async listVoices(providerName) {
7884
+ return this.speaker.listVoices(providerName);
7885
+ }
7886
+ getCapabilities(providerName) {
7887
+ return this.speaker.getCapabilities(providerName);
7888
+ }
7889
+ getProviders() {
7890
+ return this.speaker.getProviders();
7891
+ }
7892
+ isPlaying() {
7893
+ return this.speaker.isPlaying();
7894
+ }
7895
+ isPausedState() {
7896
+ return this.speaker.isPausedState();
7897
+ }
7898
+ async destroy() {
7899
+ return this.speaker.destroy();
7900
+ }
7901
+ getTimestamp() {
7902
+ const now = /* @__PURE__ */ new Date();
7903
+ const pad = (n) => n.toString().padStart(2, "0");
7904
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
7905
+ }
7906
+ };
7907
+ var defaultSpeakerService;
7908
+ function getDefaultSpeakerService() {
7909
+ if (!defaultSpeakerService) {
7910
+ defaultSpeakerService = new SpeakerService();
7911
+ }
7912
+ return defaultSpeakerService;
7913
+ }
7914
+ async function speak2(text, options) {
7915
+ if (options) {
7916
+ return speak(text, options);
7917
+ }
7918
+ return speak(text);
7919
+ }
7920
+ async function stop2() {
7921
+ return stop();
7922
+ }
7923
+ function pause2() {
7924
+ pause();
7925
+ }
7926
+ function resume2() {
7927
+ resume();
7928
+ }
7929
+ async function listVoices2(providerName) {
7930
+ return listVoices(providerName);
7931
+ }
7932
+
7933
+ // src/services/streaming-service.ts
7934
+ import { EventEmitter as EventEmitter4 } from "events";
7935
+
7936
+ // src/core/stream-player.ts
7937
+ import { EventEmitter as EventEmitter3 } from "events";
7938
+ var StreamPlayer = class extends EventEmitter3 {
7939
+ backend = null;
7940
+ _bytesWritten = 0;
7941
+ _started = false;
7942
+ _paused = false;
7943
+ _stopped = false;
7944
+ format = "mp3";
7945
+ events;
7946
+ constructor(options = {}) {
7947
+ super();
7948
+ this.format = options.format || "mp3";
7949
+ this.events = options.events;
7950
+ const backendType = options.backendType || "naudiodon" /* NAUDIODON */;
7951
+ this.backend = createBackend(backendType, {
7952
+ format: this.format,
7953
+ events: {
7954
+ onStart: () => {
7955
+ this.events?.onStart?.();
7956
+ this.emit("start");
7957
+ },
7958
+ onEnd: () => {
7959
+ this.events?.onEnd?.();
7960
+ this.emit("end");
7961
+ },
7962
+ onError: (error) => {
7963
+ this.handleError(error);
7964
+ },
7965
+ onPause: () => {
7966
+ this._paused = true;
7967
+ this.events?.onPause?.();
7968
+ this.emit("pause");
7969
+ },
7970
+ onResume: () => {
7971
+ this._paused = false;
7972
+ this.events?.onResume?.();
7973
+ this.emit("resume");
7974
+ },
7975
+ onStop: () => {
7976
+ this.events?.onStop?.();
7977
+ this.emit("stop");
7978
+ },
7979
+ onProgress: (bytes) => {
7980
+ this.events?.onProgress?.(bytes);
7981
+ this.emit("progress", bytes);
7982
+ }
7983
+ }
7984
+ });
7985
+ }
7986
+ /**
7987
+ * 开始播放
7988
+ * 初始化后端,准备接收音频数据
7989
+ */
7990
+ start() {
7991
+ if (this._started) {
7992
+ return;
7993
+ }
7994
+ if (!this.backend) {
7995
+ this.handleError(new Error("Audio backend not initialized"));
7996
+ return;
7997
+ }
7998
+ this.backend.start("");
7999
+ this._started = true;
8000
+ this._stopped = false;
8001
+ this._paused = false;
8002
+ this._bytesWritten = 0;
8003
+ }
8004
+ /**
8005
+ * 写入音频数据块(边收边播)
8006
+ * 如果尚未 start(),会自动调用
8007
+ */
8008
+ write(chunk) {
8009
+ if (this._stopped) {
8010
+ return;
8011
+ }
8012
+ if (!this._started) {
8013
+ this.start();
8014
+ }
8015
+ if (this.backend) {
8016
+ this.backend.write(chunk);
8017
+ this._bytesWritten += chunk.length;
8018
+ this.events?.onProgress?.(this._bytesWritten);
8019
+ this.emit("progress", this._bytesWritten);
8020
+ }
8021
+ }
8022
+ /**
8023
+ * 结束写入
8024
+ * 通知后端写入完成,但保持播放直到结束
8025
+ */
8026
+ end() {
8027
+ if (this.backend) {
8028
+ this.backend.end();
8029
+ }
8030
+ }
8031
+ /**
8032
+ * 停止播放
8033
+ * 立即停止播放并释放资源
8034
+ */
8035
+ stop() {
8036
+ this._stopped = true;
8037
+ this._started = false;
8038
+ this._paused = false;
8039
+ if (this.backend) {
8040
+ this.backend.stop();
8041
+ }
8042
+ this._bytesWritten = 0;
8043
+ this.events?.onStop?.();
8044
+ this.emit("stop");
8045
+ }
8046
+ /**
8047
+ * 暂停播放
8048
+ */
8049
+ pause() {
8050
+ if (!this._started || this._paused || this._stopped) {
8051
+ return;
8052
+ }
8053
+ if (this.backend) {
8054
+ this.backend.pause();
8055
+ }
8056
+ }
8057
+ /**
8058
+ * 恢复播放
8059
+ */
8060
+ resume() {
8061
+ if (!this._paused || this._stopped) {
8062
+ return;
8063
+ }
8064
+ if (this.backend) {
8065
+ this.backend.resume();
8066
+ }
8067
+ }
8068
+ /**
8069
+ * 是否已启动
8070
+ */
8071
+ isStarted() {
8072
+ return this._started;
8073
+ }
8074
+ /**
8075
+ * 是否暂停
8076
+ */
8077
+ isPaused() {
8078
+ return this._paused;
8079
+ }
8080
+ /**
8081
+ * 是否已停止
8082
+ */
8083
+ isStopped() {
8084
+ return this._stopped;
8085
+ }
8086
+ /**
8087
+ * 获取已写入的字节数
8088
+ */
8089
+ getBytesWritten() {
8090
+ return this._bytesWritten;
8091
+ }
8092
+ /**
8093
+ * 处理错误
8094
+ */
8095
+ handleError(error) {
8096
+ this.events?.onError?.(error);
8097
+ this.emit("error", error);
8098
+ }
8099
+ };
8100
+
8101
+ // src/services/streaming-service.ts
8102
+ var StreamingService = class extends EventEmitter4 {
8103
+ player = null;
8104
+ providerName;
8105
+ voice;
8106
+ speed;
8107
+ volume;
8108
+ pitch;
8109
+ backendType;
8110
+ _isActive = false;
8111
+ _bytesWritten = 0;
8112
+ constructor(options = {}) {
8113
+ super();
8114
+ this.providerName = options.provider || "minimax";
8115
+ this.voice = options.voice;
8116
+ this.speed = options.speed;
8117
+ this.volume = options.volume;
8118
+ this.pitch = options.pitch;
8119
+ this.backendType = options.backendType || "naudiodon" /* NAUDIODON */;
8120
+ }
8121
+ /**
8122
+ * 获取时间戳
8123
+ */
8124
+ getTimestamp() {
8125
+ const now = /* @__PURE__ */ new Date();
8126
+ const pad = (n) => n.toString().padStart(2, "0");
8127
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
8128
+ }
8129
+ /**
8130
+ * 初始化播放器
8131
+ */
8132
+ initPlayer() {
8133
+ if (this.player) {
8134
+ this.player.stop();
8135
+ this.player = null;
8136
+ }
8137
+ const playerOptions = {
8138
+ format: "mp3",
8139
+ backendType: this.backendType,
8140
+ events: {
8141
+ onStart: () => {
8142
+ const timestamp = this.getTimestamp();
8143
+ logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u5F00\u59CB}`);
8144
+ this.emit("start");
8145
+ },
8146
+ onEnd: () => {
8147
+ const timestamp = this.getTimestamp();
8148
+ logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u7ED3\u675F}`);
8149
+ this._isActive = false;
8150
+ this.emit("end");
8151
+ },
8152
+ onError: (error) => {
8153
+ const timestamp = this.getTimestamp();
8154
+ logger.error(`[Ocosay][${timestamp}][ERROR][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u9519\u8BEF} - ${error.message}`);
8155
+ this._isActive = false;
8156
+ this.emit("error", error);
8157
+ },
8158
+ onProgress: (bytes) => {
8159
+ this._bytesWritten = bytes;
8160
+ this.emit("progress", bytes);
8161
+ },
8162
+ onPause: () => {
8163
+ const timestamp = this.getTimestamp();
8164
+ logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u6682\u505C}`);
8165
+ this.emit("pause");
8166
+ },
8167
+ onResume: () => {
8168
+ const timestamp = this.getTimestamp();
8169
+ logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u6062\u590D}`);
8170
+ this.emit("resume");
8171
+ },
8172
+ onStop: () => {
8173
+ const timestamp = this.getTimestamp();
8174
+ logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u505C\u6B62}`);
8175
+ this._isActive = false;
8176
+ this._bytesWritten = 0;
8177
+ this.emit("stop");
8178
+ }
8179
+ }
8180
+ };
8181
+ this.player = new StreamPlayer(playerOptions);
8182
+ return this.player;
8183
+ }
8184
+ /**
8185
+ * 流式播放文本
8186
+ * 边接收边播放(豆包模式)
8187
+ */
8188
+ async stream(text) {
8189
+ if (!text || text.trim().length === 0) {
8190
+ const timestamp2 = this.getTimestamp();
8191
+ logger.warn(`[Ocosay][${timestamp2}][WARNING][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u7A7A\u6587\u672C\u8DF3\u8FC7}`);
8192
+ return;
8193
+ }
8194
+ const timestamp = this.getTimestamp();
8195
+ logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u5F00\u59CB} - \u6587\u672C\u957F\u5EA6: ${text.length}`);
8196
+ try {
8197
+ const provider = getProvider(this.providerName);
8198
+ if (!provider) {
8199
+ throw new TTSError(
8200
+ `Provider ${this.providerName} not found`,
8201
+ "UNKNOWN" /* UNKNOWN */,
8202
+ this.providerName
8203
+ );
8204
+ }
8205
+ const player = this.initPlayer();
8206
+ player.start();
8207
+ this._isActive = true;
8208
+ this._bytesWritten = 0;
8209
+ const result = await provider.speak(text, {
8210
+ voice: this.voice,
8211
+ model: "stream",
8212
+ speed: this.speed,
8213
+ volume: this.volume,
8214
+ pitch: this.pitch
8215
+ });
8216
+ await this.processAudioResult(result, player);
8217
+ } catch (error) {
8218
+ const ts = this.getTimestamp();
8219
+ const errorMsg = error instanceof Error ? error.message : String(error);
8220
+ logger.error(`[Ocosay][${ts}][ERROR][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u9519\u8BEF} - ${errorMsg}`);
8221
+ this._isActive = false;
8222
+ throw error;
8223
+ }
8224
+ }
8225
+ /**
8226
+ * 处理音频结果
8227
+ */
8228
+ async processAudioResult(result, player) {
8229
+ if (result.isStream && result.audioData instanceof ReadableStream) {
8230
+ await this.streamAudioChunks(result.audioData, player);
8231
+ } else if (Buffer.isBuffer(result.audioData)) {
8232
+ player.write(result.audioData);
8233
+ player.end();
8234
+ }
8235
+ }
8236
+ /**
8237
+ * 流式处理音频chunk
8238
+ */
8239
+ async streamAudioChunks(stream2, player) {
8240
+ const reader = stream2.getReader();
8241
+ try {
8242
+ while (true) {
8243
+ const { done, value } = await reader.read();
8244
+ if (done) {
8245
+ break;
8246
+ }
8247
+ if (value) {
8248
+ const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
8249
+ player.write(chunk);
8250
+ }
8251
+ }
8252
+ } finally {
8253
+ reader.releaseLock();
8254
+ player.end();
8255
+ }
8256
+ }
8257
+ /**
8258
+ * 停止流式播放
8259
+ */
8260
+ stop() {
8261
+ if (this.player) {
8262
+ this.player.stop();
8263
+ }
8264
+ this._isActive = false;
8265
+ this._bytesWritten = 0;
8266
+ }
8267
+ /**
8268
+ * 暂停流式播放
8269
+ */
8270
+ pause() {
8271
+ if (this.player) {
8272
+ this.player.pause();
8273
+ }
8274
+ }
8275
+ /**
8276
+ * 恢复流式播放
8277
+ */
8278
+ resume() {
8279
+ if (this.player) {
8280
+ this.player.resume();
8281
+ }
8282
+ }
8283
+ /**
8284
+ * 获取流式播放状态
7813
8285
  */
7814
- getProviders() {
7815
- return listProviders();
8286
+ getStatus() {
8287
+ return {
8288
+ isActive: this._isActive,
8289
+ bytesWritten: this._bytesWritten,
8290
+ state: this.player?.isStopped() ? "stopped" : this.player?.isPaused() ? "paused" : this._isActive ? "playing" : "idle"
8291
+ };
7816
8292
  }
7817
8293
  /**
7818
- * 是否正在播放
8294
+ * 是否处于活跃状态
7819
8295
  */
7820
- isPlaying() {
7821
- return this.isSpeaking && !this.isPaused;
8296
+ isActive() {
8297
+ return this._isActive;
7822
8298
  }
7823
8299
  /**
7824
- * 是否暂停
8300
+ * 销毁服务
7825
8301
  */
7826
- isPausedState() {
7827
- return this.isPaused;
8302
+ async destroy() {
8303
+ if (this.player) {
8304
+ this.player.stop();
8305
+ this.player = null;
8306
+ }
8307
+ this._isActive = false;
8308
+ this._bytesWritten = 0;
7828
8309
  }
7829
8310
  };
7830
- var defaultSpeaker;
7831
- function getDefaultSpeaker() {
7832
- if (!defaultSpeaker) {
7833
- defaultSpeaker = new Speaker();
8311
+ var defaultStreamingService;
8312
+ function getDefaultStreamingService() {
8313
+ if (!defaultStreamingService) {
8314
+ defaultStreamingService = new StreamingService();
7834
8315
  }
7835
- return defaultSpeaker;
7836
- }
7837
- async function speak(text, options) {
7838
- const speaker2 = getDefaultSpeaker();
7839
- return speaker2.speak(text, options);
7840
- }
7841
- async function stop() {
7842
- const speaker2 = getDefaultSpeaker();
7843
- return speaker2.stop();
7844
- }
7845
- function pause() {
7846
- const speaker2 = getDefaultSpeaker();
7847
- speaker2.pause();
7848
- }
7849
- function resume() {
7850
- const speaker2 = getDefaultSpeaker();
7851
- speaker2.resume();
8316
+ return defaultStreamingService;
7852
8317
  }
7853
- async function listVoices(providerName) {
7854
- const speaker2 = getDefaultSpeaker();
7855
- return speaker2.listVoices(providerName);
8318
+ async function stream(text, options) {
8319
+ const service = options ? new StreamingService(options) : getDefaultStreamingService();
8320
+ return service.stream(text);
7856
8321
  }
7857
8322
 
7858
8323
  // src/tools/tts.ts
@@ -7871,11 +8336,20 @@ function extractTextArg(args) {
7871
8336
  logger.warn("received text7 instead of text from OpenCode framework");
7872
8337
  return text7.trim();
7873
8338
  }
7874
- if (typeof text7 === "object" && "content" in text7) {
7875
- const content = text7.content;
7876
- if (typeof content === "string" && content.trim().length > 0) {
7877
- logger.warn("text7 is an object with content field");
7878
- return content.trim();
8339
+ if (typeof text7 === "object") {
8340
+ if ("split" in text7 && "content" in text7) {
8341
+ const content = text7.content;
8342
+ if (typeof content === "string" && content.trim().length > 0) {
8343
+ logger.info("text7 split format detected");
8344
+ return content.trim();
8345
+ }
8346
+ }
8347
+ if ("content" in text7) {
8348
+ const content = text7.content;
8349
+ if (typeof content === "string" && content.trim().length > 0) {
8350
+ logger.info("text7 content format detected");
8351
+ return content.trim();
8352
+ }
7879
8353
  }
7880
8354
  }
7881
8355
  logger.warn({ type: typeof text7 }, "text7 is not a valid string or object with content");
@@ -7902,29 +8376,29 @@ async function handleToolCall(toolName, args) {
7902
8376
  if (!text) {
7903
8377
  return { success: false, error: "No valid text found in args" };
7904
8378
  }
7905
- await speak(text);
8379
+ await speak2(text);
7906
8380
  return { success: true, message: "Speech completed" };
7907
8381
  }
7908
8382
  case "tts_stop":
7909
- await stop();
8383
+ await stop2();
7910
8384
  return { success: true, message: "Stopped" };
7911
8385
  case "tts_pause":
7912
- pause();
8386
+ pause2();
7913
8387
  return { success: true, message: "Paused" };
7914
8388
  case "tts_resume":
7915
- resume();
8389
+ resume2();
7916
8390
  return { success: true, message: "Resumed" };
7917
8391
  case "tts_list_voices": {
7918
- const voices = await listVoices(args?.provider);
8392
+ const voices = await listVoices2(args?.provider);
7919
8393
  return { success: true, voices };
7920
8394
  }
7921
8395
  case "tts_list_providers": {
7922
- const speaker2 = getDefaultSpeaker();
8396
+ const speaker2 = getDefaultSpeakerService();
7923
8397
  const providers2 = speaker2.getProviders();
7924
8398
  return { success: true, providers: providers2 };
7925
8399
  }
7926
8400
  case "tts_status": {
7927
- const s = getDefaultSpeaker();
8401
+ const s = getDefaultSpeakerService();
7928
8402
  return {
7929
8403
  success: true,
7930
8404
  isPlaying: s.isPlaying(),
@@ -7946,14 +8420,14 @@ async function handleToolCall(toolName, args) {
7946
8420
  "tts_stream"
7947
8421
  );
7948
8422
  }
7949
- const streamReader2 = getStreamReader();
7950
- const synthesizer = getStreamingSynthesizer();
7951
- if (streamReader2 && synthesizer) {
7952
- streamReader2.start();
8423
+ const streamingService = getDefaultStreamingService();
8424
+ if (streamingService) {
7953
8425
  const textArg = extractTextArg(args);
7954
8426
  if (textArg && typeof textArg === "string" && textArg.trim().length > 0) {
7955
8427
  logger.info({ text: textArg.substring(0, 50) + "..." }, "synthesizing text");
7956
- synthesizer.synthesize(textArg);
8428
+ stream(textArg).catch((error) => {
8429
+ logger.error({ error }, "stream failed");
8430
+ });
7957
8431
  }
7958
8432
  return { success: true, message: "Stream speak started" };
7959
8433
  }
@@ -7971,13 +8445,13 @@ async function handleToolCall(toolName, args) {
7971
8445
  "tts_stream"
7972
8446
  );
7973
8447
  }
7974
- const player = getStreamPlayer();
7975
- if (player) {
7976
- player.stop();
8448
+ const streamingService = getDefaultStreamingService();
8449
+ if (streamingService) {
8450
+ streamingService.stop();
7977
8451
  return { success: true, message: "Stream stopped" };
7978
8452
  }
7979
8453
  throw new TTSError(
7980
- "Stream player not available",
8454
+ "Stream service not available",
7981
8455
  "UNKNOWN" /* UNKNOWN */,
7982
8456
  "tts_stream"
7983
8457
  );
@@ -8105,34 +8579,39 @@ var MiniMaxProvider = class extends BaseTTSProvider {
8105
8579
  },
8106
8580
  responseType: "stream"
8107
8581
  });
8108
- const stream = response.data;
8582
+ const stream2 = response.data;
8109
8583
  const audioChunks = [];
8584
+ let lineBuffer = "";
8110
8585
  return new Promise((resolve, reject) => {
8111
- stream.on("data", (chunk) => {
8112
- try {
8113
- const lines = chunk.toString().split("\n");
8114
- for (const line of lines) {
8115
- if (line.startsWith("data:")) {
8116
- const data = JSON.parse(line.slice(5));
8117
- if (data.data?.audio) {
8118
- audioChunks.push(Buffer.from(data.data.audio, "hex"));
8119
- }
8120
- if (data.data?.status === 2) {
8121
- const fullAudio = Buffer.concat(audioChunks);
8122
- resolve({
8123
- audioData: fullAudio,
8124
- format: this.audioFormat,
8125
- isStream: true,
8126
- duration: this.estimateDuration(fullAudio.length)
8127
- });
8128
- }
8586
+ stream2.on("data", (chunk) => {
8587
+ lineBuffer += chunk.toString();
8588
+ while (true) {
8589
+ const lineEnd = lineBuffer.indexOf("\n");
8590
+ if (lineEnd === -1) break;
8591
+ const line = lineBuffer.slice(0, lineEnd).trim();
8592
+ lineBuffer = lineBuffer.slice(lineEnd + 1);
8593
+ if (!line || !line.startsWith("data:")) continue;
8594
+ const jsonStr = line.slice(5).trim();
8595
+ if (!jsonStr) continue;
8596
+ try {
8597
+ const data = JSON.parse(jsonStr);
8598
+ if (data.audio) {
8599
+ audioChunks.push(Buffer.from(data.audio, "hex"));
8600
+ }
8601
+ if (data.is_final === true) {
8602
+ const fullAudio = Buffer.concat(audioChunks);
8603
+ resolve({
8604
+ audioData: fullAudio,
8605
+ format: this.audioFormat,
8606
+ isStream: true,
8607
+ duration: this.estimateDuration(fullAudio.length)
8608
+ });
8129
8609
  }
8610
+ } catch (e) {
8130
8611
  }
8131
- } catch (e) {
8132
- audioChunks.push(chunk);
8133
8612
  }
8134
8613
  });
8135
- stream.on("error", (err) => {
8614
+ stream2.on("error", (err) => {
8136
8615
  reject(new TTSError(
8137
8616
  "Stream error",
8138
8617
  "NETWORK" /* NETWORK */,
@@ -8140,7 +8619,19 @@ var MiniMaxProvider = class extends BaseTTSProvider {
8140
8619
  err
8141
8620
  ));
8142
8621
  });
8143
- stream.on("end", () => {
8622
+ stream2.on("end", () => {
8623
+ if (lineBuffer.trim() && lineBuffer.startsWith("data:")) {
8624
+ const jsonStr = lineBuffer.slice(5).trim();
8625
+ if (jsonStr) {
8626
+ try {
8627
+ const data = JSON.parse(jsonStr);
8628
+ if (data.audio) {
8629
+ audioChunks.push(Buffer.from(data.audio, "hex"));
8630
+ }
8631
+ } catch (e) {
8632
+ }
8633
+ }
8634
+ }
8144
8635
  if (audioChunks.length > 0) {
8145
8636
  const fullAudio = Buffer.concat(audioChunks);
8146
8637
  resolve({
@@ -8430,8 +8921,8 @@ var MINIMAX_VOICES = [
8430
8921
  ];
8431
8922
 
8432
8923
  // src/core/stream-reader.ts
8433
- import { EventEmitter as EventEmitter3 } from "events";
8434
- var StreamReader = class extends EventEmitter3 {
8924
+ import { EventEmitter as EventEmitter5 } from "events";
8925
+ var StreamReader = class extends EventEmitter5 {
8435
8926
  constructor(bufferSize = 30, bufferTimeout = 2e3) {
8436
8927
  super();
8437
8928
  this.bufferSize = bufferSize;
@@ -8595,8 +9086,8 @@ var StreamReader = class extends EventEmitter3 {
8595
9086
  };
8596
9087
 
8597
9088
  // src/core/streaming-synthesizer.ts
8598
- import { EventEmitter as EventEmitter4 } from "events";
8599
- var StreamingSynthesizer = class extends EventEmitter4 {
9089
+ import { EventEmitter as EventEmitter6 } from "events";
9090
+ var StreamingSynthesizer = class extends EventEmitter6 {
8600
9091
  constructor(options) {
8601
9092
  super();
8602
9093
  this.options = options;
@@ -8622,6 +9113,7 @@ var StreamingSynthesizer = class extends EventEmitter4 {
8622
9113
  await this.processAudioResult(result);
8623
9114
  this.emit("done");
8624
9115
  } catch (error) {
9116
+ logger.error({ error }, "synthesize failed");
8625
9117
  const ttsError = error instanceof TTSError ? error : new TTSError(
8626
9118
  error instanceof Error ? error.message : "Synthesis failed",
8627
9119
  "UNKNOWN",
@@ -8644,8 +9136,8 @@ var StreamingSynthesizer = class extends EventEmitter4 {
8644
9136
  /**
8645
9137
  * 处理 ReadableStream,逐chunk emit
8646
9138
  */
8647
- async processReadableStream(stream) {
8648
- const reader = stream.getReader();
9139
+ async processReadableStream(stream2) {
9140
+ const reader = stream2.getReader();
8649
9141
  try {
8650
9142
  while (true) {
8651
9143
  const { done, value } = await reader.read();
@@ -8684,171 +9176,6 @@ var StreamingSynthesizer = class extends EventEmitter4 {
8684
9176
  }
8685
9177
  };
8686
9178
 
8687
- // src/core/stream-player.ts
8688
- import { EventEmitter as EventEmitter5 } from "events";
8689
- var StreamPlayer = class extends EventEmitter5 {
8690
- backend = null;
8691
- _bytesWritten = 0;
8692
- _started = false;
8693
- _paused = false;
8694
- _stopped = false;
8695
- format = "mp3";
8696
- events;
8697
- constructor(options = {}) {
8698
- super();
8699
- this.format = options.format || "mp3";
8700
- this.events = options.events;
8701
- const backendType = options.backendType || "naudiodon" /* NAUDIODON */;
8702
- this.backend = createBackend(backendType, {
8703
- format: this.format,
8704
- events: {
8705
- onStart: () => {
8706
- this.events?.onStart?.();
8707
- this.emit("start");
8708
- },
8709
- onEnd: () => {
8710
- this.events?.onEnd?.();
8711
- this.emit("end");
8712
- },
8713
- onError: (error) => {
8714
- this.handleError(error);
8715
- },
8716
- onPause: () => {
8717
- this._paused = true;
8718
- this.events?.onPause?.();
8719
- this.emit("pause");
8720
- },
8721
- onResume: () => {
8722
- this._paused = false;
8723
- this.events?.onResume?.();
8724
- this.emit("resume");
8725
- },
8726
- onStop: () => {
8727
- this.events?.onStop?.();
8728
- this.emit("stop");
8729
- },
8730
- onProgress: (bytes) => {
8731
- this.events?.onProgress?.(bytes);
8732
- this.emit("progress", bytes);
8733
- }
8734
- }
8735
- });
8736
- }
8737
- /**
8738
- * 开始播放
8739
- * 初始化后端,准备接收音频数据
8740
- */
8741
- start() {
8742
- if (this._started) {
8743
- return;
8744
- }
8745
- if (!this.backend) {
8746
- this.handleError(new Error("Audio backend not initialized"));
8747
- return;
8748
- }
8749
- this.backend.start("");
8750
- this._started = true;
8751
- this._stopped = false;
8752
- this._paused = false;
8753
- this._bytesWritten = 0;
8754
- }
8755
- /**
8756
- * 写入音频数据块(边收边播)
8757
- * 如果尚未 start(),会自动调用
8758
- */
8759
- write(chunk) {
8760
- if (this._stopped) {
8761
- return;
8762
- }
8763
- if (!this._started) {
8764
- this.start();
8765
- }
8766
- if (this.backend) {
8767
- this.backend.write(chunk);
8768
- this._bytesWritten += chunk.length;
8769
- this.events?.onProgress?.(this._bytesWritten);
8770
- this.emit("progress", this._bytesWritten);
8771
- }
8772
- }
8773
- /**
8774
- * 结束写入
8775
- * 通知后端写入完成,但保持播放直到结束
8776
- */
8777
- end() {
8778
- if (this.backend) {
8779
- this.backend.end();
8780
- }
8781
- }
8782
- /**
8783
- * 停止播放
8784
- * 立即停止播放并释放资源
8785
- */
8786
- stop() {
8787
- this._stopped = true;
8788
- this._started = false;
8789
- this._paused = false;
8790
- if (this.backend) {
8791
- this.backend.stop();
8792
- }
8793
- this._bytesWritten = 0;
8794
- this.events?.onStop?.();
8795
- this.emit("stop");
8796
- }
8797
- /**
8798
- * 暂停播放
8799
- */
8800
- pause() {
8801
- if (!this._started || this._paused || this._stopped) {
8802
- return;
8803
- }
8804
- if (this.backend) {
8805
- this.backend.pause();
8806
- }
8807
- }
8808
- /**
8809
- * 恢复播放
8810
- */
8811
- resume() {
8812
- if (!this._paused || this._stopped) {
8813
- return;
8814
- }
8815
- if (this.backend) {
8816
- this.backend.resume();
8817
- }
8818
- }
8819
- /**
8820
- * 是否已启动
8821
- */
8822
- isStarted() {
8823
- return this._started;
8824
- }
8825
- /**
8826
- * 是否暂停
8827
- */
8828
- isPaused() {
8829
- return this._paused;
8830
- }
8831
- /**
8832
- * 是否已停止
8833
- */
8834
- isStopped() {
8835
- return this._stopped;
8836
- }
8837
- /**
8838
- * 获取已写入的字节数
8839
- */
8840
- getBytesWritten() {
8841
- return this._bytesWritten;
8842
- }
8843
- /**
8844
- * 处理错误
8845
- */
8846
- handleError(error) {
8847
- this.events?.onError?.(error);
8848
- this.emit("error", error);
8849
- }
8850
- };
8851
-
8852
9179
  // src/index.ts
8853
9180
  var speaker;
8854
9181
  var streamReader;
@@ -8982,15 +9309,6 @@ function getStreamStatus() {
8982
9309
  state: streamReader.getState()
8983
9310
  };
8984
9311
  }
8985
- function getStreamReader() {
8986
- return streamReader;
8987
- }
8988
- function getStreamingSynthesizer() {
8989
- return streamingSynthesizer;
8990
- }
8991
- function getStreamPlayer() {
8992
- return streamPlayer;
8993
- }
8994
9312
 
8995
9313
  // src/config.ts
8996
9314
  import * as fs2 from "fs";
@@ -9094,6 +9412,7 @@ function loadOrCreateConfig() {
9094
9412
  try {
9095
9413
  fs2.mkdirSync(configDir, { recursive: true });
9096
9414
  } catch (err) {
9415
+ logger.error({ err }, "failed to create config directory");
9097
9416
  throw new Error(`[ocosay] \u65E0\u6CD5\u521B\u5EFA\u914D\u7F6E\u76EE\u5F55 ${configDir}: ${err}`);
9098
9417
  }
9099
9418
  }
@@ -9109,6 +9428,7 @@ function loadOrCreateConfig() {
9109
9428
  logger.warn({ err }, "failed to set config file permissions");
9110
9429
  }
9111
9430
  } catch (err) {
9431
+ logger.error({ err }, "failed to write config file");
9112
9432
  throw new Error(`[ocosay] cannot write config file ${CONFIG_PATH}: ${err}`);
9113
9433
  }
9114
9434
  logger.info({ path: CONFIG_PATH }, "config file created");
@@ -9139,6 +9459,87 @@ function loadOrCreateConfig() {
9139
9459
  }
9140
9460
  }
9141
9461
 
9462
+ // src/services/notification-service.ts
9463
+ var instance;
9464
+ var tui = null;
9465
+ var initialized2 = false;
9466
+ var NotificationService = class _NotificationService {
9467
+ constructor() {
9468
+ }
9469
+ static getInstance() {
9470
+ if (!instance) {
9471
+ instance = new _NotificationService();
9472
+ }
9473
+ return instance;
9474
+ }
9475
+ initialize(tuiInstance) {
9476
+ if (initialized2) return;
9477
+ tui = tuiInstance;
9478
+ initialized2 = true;
9479
+ logger.debug("NotificationService initialized");
9480
+ }
9481
+ isReady() {
9482
+ return initialized2 && tui !== null;
9483
+ }
9484
+ showToast(message, type = "info") {
9485
+ const title = this.getTitleForType(type);
9486
+ if (tui?.showToast) {
9487
+ try {
9488
+ tui.showToast({
9489
+ title,
9490
+ message,
9491
+ variant: type,
9492
+ duration: type === "error" ? 8e3 : 5e3
9493
+ });
9494
+ return;
9495
+ } catch (err) {
9496
+ logger.warn({ err }, "tui.showToast failed");
9497
+ }
9498
+ }
9499
+ this.fallbackLog(type, title, message);
9500
+ }
9501
+ success(message) {
9502
+ this.showToast(message, "success");
9503
+ }
9504
+ error(message) {
9505
+ this.showToast(message, "error");
9506
+ }
9507
+ warning(message) {
9508
+ this.showToast(message, "warning");
9509
+ }
9510
+ info(message) {
9511
+ this.showToast(message, "info");
9512
+ }
9513
+ getTitleForType(type) {
9514
+ const titles = {
9515
+ success: "Success",
9516
+ error: "Error",
9517
+ warning: "Warning",
9518
+ info: "Info"
9519
+ };
9520
+ return titles[type];
9521
+ }
9522
+ fallbackLog(type, title, message) {
9523
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
9524
+ switch (type) {
9525
+ case "error":
9526
+ logger.error({ title, message, timestamp }, "Toast (fallback)");
9527
+ break;
9528
+ case "warning":
9529
+ logger.warn({ title, message, timestamp }, "Toast (fallback)");
9530
+ break;
9531
+ default:
9532
+ logger.info({ title, message, timestamp }, "Toast (fallback)");
9533
+ }
9534
+ }
9535
+ };
9536
+ function showToast(message, type = "info") {
9537
+ NotificationService.getInstance().showToast(message, type);
9538
+ }
9539
+ function initializeNotificationService(tuiInstance) {
9540
+ NotificationService.getInstance().initialize(tuiInstance);
9541
+ }
9542
+
9142
9543
  // src/plugin.ts
9143
9544
  import { readFileSync as readFileSync2 } from "fs";
9144
9545
  import { fileURLToPath } from "url";
@@ -9286,24 +9687,12 @@ var server = (async (input, _options) => {
9286
9687
  }
9287
9688
  const opencodeTui = input.client?.tui;
9288
9689
  global.__opencode_tui__ = opencodeTui;
9690
+ initializeNotificationService(opencodeTui);
9289
9691
  setTimeout(async () => {
9290
- if (!opencodeTui?.showToast) return;
9291
9692
  if (initError) {
9292
- await opencodeTui.showToast({
9293
- body: {
9294
- title: `Ocosay v${pluginVersion} Initialization Failed`,
9295
- message: "Initialization failed, please check config",
9296
- variant: "error"
9297
- }
9298
- });
9693
+ showToast(`Ocosay v${pluginVersion} Initialization Failed: please check config`, "error");
9299
9694
  } else {
9300
- await opencodeTui.showToast({
9301
- body: {
9302
- title: `Ocosay v${pluginVersion} Plugin Loaded`,
9303
- message: `Auto-read: ${config.autoRead ? "ON" : "OFF"}`,
9304
- variant: "success"
9305
- }
9306
- });
9695
+ showToast(`Ocosay v${pluginVersion} Plugin Loaded (Auto-read: ${config.autoRead ? "ON" : "OFF"})`, "success");
9307
9696
  }
9308
9697
  }, 7e3);
9309
9698
  return {
@@ -9338,15 +9727,7 @@ var server = (async (input, _options) => {
9338
9727
  });
9339
9728
  initError = null;
9340
9729
  } catch (err) {
9341
- if (opencodeTui?.showToast) {
9342
- await opencodeTui.showToast({
9343
- body: {
9344
- title: `Ocosay v${pluginVersion} Initialization Failed`,
9345
- message: "Initialization failed, please check config",
9346
- variant: "error"
9347
- }
9348
- });
9349
- }
9730
+ showToast(`Ocosay v${pluginVersion} Initialization Failed: please check config`, "error");
9350
9731
  }
9351
9732
  }
9352
9733
  }