@deslop/workbench 0.0.315 → 0.0.320

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/dist/client/assets/agent-DAD7EQOa.js +2 -0
  2. package/dist/client/assets/{agent-BIuVSeAF.js → agent-DHWhwvQy.js} +1 -1
  3. package/dist/client/assets/{button-CP1KTzaA.js → button-fe_R2wzr.js} +11 -11
  4. package/dist/client/assets/{diff-B287sB8S.js → diff-BbjpVkn4.js} +10 -10
  5. package/dist/client/assets/diff-HFsBcdrM.js +2 -0
  6. package/dist/client/assets/{external-link-DxUqDR8g.js → external-link-CTjuCORn.js} +1 -1
  7. package/dist/client/assets/{fallbacks-D55g6vQC.js → fallbacks-DZ7ciusO.js} +1 -1
  8. package/dist/client/assets/index-Ci3BZgXN.css +2 -0
  9. package/dist/client/assets/index-Ds4rq0zQ.js +10 -0
  10. package/dist/client/assets/input-group-BtEJur4W.js +153 -0
  11. package/dist/client/assets/loader-circle-B1mHTP2Y.js +1 -0
  12. package/dist/client/assets/portless-DFKFPX3Z.js +1 -0
  13. package/dist/client/assets/portless-DexDlqwA.js +2 -0
  14. package/dist/client/assets/resizable-B1fIW9sm.js +1 -0
  15. package/dist/client/assets/route-CUHeGENe.js +45 -0
  16. package/dist/client/assets/route-DOWKJR6H.js +2 -0
  17. package/dist/client/assets/run-BvHiSlty.js +2 -0
  18. package/dist/client/assets/run-L2YCL4H0.js +1 -0
  19. package/dist/client/assets/state-T-ZhKyUm.js +2 -0
  20. package/dist/client/assets/{terminal-DWl9BK6U.js → terminal-CGe8qF7_.js} +1 -1
  21. package/dist/client/assets/{terminal-CMql1niz.js → terminal-Ci9YBovb.js} +2 -2
  22. package/dist/client/assets/terminal-t4CeG_V9.js +2 -0
  23. package/dist/client/assets/{triangle-alert-BBj9uTaq.js → triangle-alert-CGj-8H_a.js} +1 -1
  24. package/dist/client/index.html +12 -12
  25. package/dist/server.js +414 -1159
  26. package/package.json +5 -4
  27. package/dist/client/assets/agent-Cvk2rNLW.js +0 -2
  28. package/dist/client/assets/browser-ZCteqApb.js +0 -2
  29. package/dist/client/assets/browser-qFOBXYmj.js +0 -1
  30. package/dist/client/assets/composite-DrpN5NPU.js +0 -1
  31. package/dist/client/assets/dialog-DNzOF5Pr.js +0 -153
  32. package/dist/client/assets/diff-Dz1s0ttU.js +0 -2
  33. package/dist/client/assets/index-4j0hsxXB.css +0 -2
  34. package/dist/client/assets/index-C8lKBTMr.js +0 -10
  35. package/dist/client/assets/loader-circle-CjJdQ-6r.js +0 -1
  36. package/dist/client/assets/route-CaWOfZWN.js +0 -2
  37. package/dist/client/assets/route-VC_QtiiN.js +0 -45
  38. package/dist/client/assets/run-B0jQ0k3F.js +0 -2
  39. package/dist/client/assets/run-CFcWKZn5.js +0 -1
  40. package/dist/client/assets/state-m9GNWCBT.js +0 -2
  41. package/dist/client/assets/terminal-CgkXzq-O.js +0 -2
package/dist/server.js CHANGED
@@ -16,12 +16,10 @@ import { randomUUID } from "node:crypto";
16
16
  import * as NFS from "node:fs";
17
17
  import * as OS from "node:os";
18
18
  import * as Path from "node:path";
19
- import path, { join } from "node:path";
19
+ import path from "node:path";
20
20
  import * as NodeStreamP from "node:stream/promises";
21
21
  import { pipeline } from "node:stream/promises";
22
- import { readFile } from "node:fs/promises";
23
22
  import * as readline from "node:readline";
24
- import nodeProcess from "node:process";
25
23
  import * as nodePty from "@lydell/node-pty";
26
24
  //#region \0rolldown/runtime.js
27
25
  var __create = Object.create;
@@ -4360,7 +4358,7 @@ const done$2 = (value) => {
4360
4358
  * @category constructors
4361
4359
  * @since 2.0.0
4362
4360
  */
4363
- const make$65 = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
4361
+ const make$64 = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
4364
4362
  const isStrictEquivalent = (x, y) => x === y;
4365
4363
  /**
4366
4364
  * Creates an equivalence relation that uses strict equality (`===`) to compare values.
@@ -4473,7 +4471,7 @@ const strictEqual = () => isStrictEquivalent;
4473
4471
  * @since 4.0.0
4474
4472
  */
4475
4473
  function Tuple$1(elements) {
4476
- return make$65((self, that) => {
4474
+ return make$64((self, that) => {
4477
4475
  if (self.length !== that.length) return false;
4478
4476
  for (let i = 0; i < self.length; i++) if (!elements[i](self[i], that[i])) return false;
4479
4477
  return true;
@@ -4483,7 +4481,7 @@ function Tuple$1(elements) {
4483
4481
  * @since 4.0.0
4484
4482
  */
4485
4483
  function Array_(item) {
4486
- return make$65((self, that) => {
4484
+ return make$64((self, that) => {
4487
4485
  if (self.length !== that.length) return false;
4488
4486
  for (let i = 0; i < self.length; i++) if (!item(self[i], that[i])) return false;
4489
4487
  return true;
@@ -4501,9 +4499,9 @@ const isArrayNonEmpty$1 = (self) => self.length > 0;
4501
4499
  /**
4502
4500
  * @since 2.0.0
4503
4501
  */
4504
- const TypeId$51 = "~effect/data/Option";
4502
+ const TypeId$50 = "~effect/data/Option";
4505
4503
  const CommonProto$1 = {
4506
- [TypeId$51]: { _A: (_) => _ },
4504
+ [TypeId$50]: { _A: (_) => _ },
4507
4505
  ...PipeInspectableProto,
4508
4506
  [Symbol.iterator]() {
4509
4507
  return new SingleShotGen(this);
@@ -4554,7 +4552,7 @@ const NoneProto = /*#__PURE__*/ Object.assign(/*#__PURE__*/ Object.create(Common
4554
4552
  }
4555
4553
  });
4556
4554
  /** @internal */
4557
- const isOption = (input) => hasProperty(input, TypeId$51);
4555
+ const isOption = (input) => hasProperty(input, TypeId$50);
4558
4556
  /** @internal */
4559
4557
  const isNone$1 = (fa) => fa._tag === "None";
4560
4558
  /** @internal */
@@ -4569,9 +4567,9 @@ const some$2 = (value) => {
4569
4567
  };
4570
4568
  //#endregion
4571
4569
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/internal/result.js
4572
- const TypeId$50 = "~effect/data/Result";
4570
+ const TypeId$49 = "~effect/data/Result";
4573
4571
  const CommonProto = {
4574
- [TypeId$50]: {
4572
+ [TypeId$49]: {
4575
4573
  /* v8 ignore next 2 */
4576
4574
  _A: (_) => _,
4577
4575
  _E: (_) => _
@@ -4622,7 +4620,7 @@ const FailureProto = /*#__PURE__*/ Object.assign(/*#__PURE__*/ Object.create(Com
4622
4620
  }
4623
4621
  });
4624
4622
  /** @internal */
4625
- const isResult = (input) => hasProperty(input, TypeId$50);
4623
+ const isResult = (input) => hasProperty(input, TypeId$49);
4626
4624
  /** @internal */
4627
4625
  const isFailure$2 = (result) => result._tag === "Failure";
4628
4626
  /** @internal */
@@ -4756,7 +4754,7 @@ const succeed$8 = (success) => {
4756
4754
  * @category constructors
4757
4755
  * @since 2.0.0
4758
4756
  */
4759
- function make$64(compare) {
4757
+ function make$63(compare) {
4760
4758
  return (self, that) => self === that ? 0 : compare(self, that);
4761
4759
  }
4762
4760
  /**
@@ -4789,7 +4787,7 @@ function make$64(compare) {
4789
4787
  * @category instances
4790
4788
  * @since 4.0.0
4791
4789
  */
4792
- const String$5 = /*#__PURE__*/ make$64((self, that) => self < that ? -1 : 1);
4790
+ const String$5 = /*#__PURE__*/ make$63((self, that) => self < that ? -1 : 1);
4793
4791
  /**
4794
4792
  * Order instance for numbers that compares them numerically.
4795
4793
  *
@@ -4824,7 +4822,7 @@ const String$5 = /*#__PURE__*/ make$64((self, that) => self < that ? -1 : 1);
4824
4822
  * @category instances
4825
4823
  * @since 4.0.0
4826
4824
  */
4827
- const Number$5 = /*#__PURE__*/ make$64((self, that) => {
4825
+ const Number$5 = /*#__PURE__*/ make$63((self, that) => {
4828
4826
  if (globalThis.Number.isNaN(self) && globalThis.Number.isNaN(that)) return 0;
4829
4827
  if (globalThis.Number.isNaN(self)) return -1;
4830
4828
  if (globalThis.Number.isNaN(that)) return 1;
@@ -4863,7 +4861,7 @@ const Number$5 = /*#__PURE__*/ make$64((self, that) => {
4863
4861
  * @category mapping
4864
4862
  * @since 2.0.0
4865
4863
  */
4866
- const mapInput = /*#__PURE__*/ dual(2, (self, f) => make$64((b1, b2) => self(f(b1), f(b2))));
4864
+ const mapInput = /*#__PURE__*/ dual(2, (self, f) => make$63((b1, b2) => self(f(b1), f(b2))));
4867
4865
  /**
4868
4866
  * Checks whether one value is strictly less than another according to the given order.
4869
4867
  *
@@ -5443,42 +5441,6 @@ const flatMap$6 = /*#__PURE__*/ dual(2, (self, f) => isNone(self) ? none() : f(s
5443
5441
  * @since 2.0.0
5444
5442
  */
5445
5443
  const filter$3 = /*#__PURE__*/ dual(2, (self, predicate) => isNone(self) ? none() : predicate(self.value) ? some$1(self.value) : none());
5446
- /**
5447
- * Lifts a `Predicate` or `Refinement` into the `Option` context: returns
5448
- * `Some(value)` when the predicate holds, `None` otherwise.
5449
- *
5450
- * **When to use**
5451
- *
5452
- * Use to convert a boolean check into an `Option`-returning function
5453
- * - Validating input and wrapping it in `Option`
5454
- *
5455
- * **Details**
5456
- *
5457
- * - `predicate(value)` is `true` → `Some(value)`
5458
- * - `predicate(value)` is `false` → `None`
5459
- * - Supports refinements for type narrowing
5460
- *
5461
- * **Example** (Validating positive numbers)
5462
- *
5463
- * ```ts
5464
- * import { Option } from "effect"
5465
- *
5466
- * const parsePositive = Option.liftPredicate((n: number) => n > 0)
5467
- *
5468
- * console.log(parsePositive(1))
5469
- * // Output: { _id: 'Option', _tag: 'Some', value: 1 }
5470
- *
5471
- * console.log(parsePositive(-1))
5472
- * // Output: { _id: 'Option', _tag: 'None' }
5473
- * ```
5474
- *
5475
- * @see {@link filter} to apply a predicate to an existing `Option`
5476
- * @see {@link toRefinement} for the inverse direction
5477
- *
5478
- * @category lifting
5479
- * @since 2.0.0
5480
- */
5481
- const liftPredicate = /*#__PURE__*/ dual(2, (b, predicate) => predicate(b) ? some$1(b) : none());
5482
5444
  //#endregion
5483
5445
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Result.js
5484
5446
  /**
@@ -5668,34 +5630,6 @@ const match$4 = /*#__PURE__*/ dual(2, (self, { onFailure, onSuccess }) => isFail
5668
5630
  //#endregion
5669
5631
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Tuple.js
5670
5632
  /**
5671
- * Creates a tuple from the provided arguments.
5672
- *
5673
- * **When to use**
5674
- *
5675
- * Use when you use this instead of `[a, b, c] as const` when you want a properly typed tuple
5676
- * without a manual cast.
5677
- *
5678
- * **Details**
5679
- *
5680
- * The returned value has the exact tuple type, with each element's literal type
5681
- * preserved.
5682
- *
5683
- * **Example** (Creating a tuple)
5684
- *
5685
- * ```ts
5686
- * import { Tuple } from "effect"
5687
- *
5688
- * const point = Tuple.make(10, 20, "red")
5689
- * console.log(point) // [10, 20, "red"]
5690
- * ```
5691
- *
5692
- * @see {@link get} – access a single element by index
5693
- * @see {@link appendElement} – append an element to a tuple
5694
- * @category constructors
5695
- * @since 2.0.0
5696
- */
5697
- const make$63 = (...elements) => elements;
5698
- /**
5699
5633
  * Creates an `Equivalence` for tuples by comparing corresponding elements
5700
5634
  * using the provided per-position `Equivalence`s. Two tuples are equivalent
5701
5635
  * when all their corresponding elements are equivalent.
@@ -5816,27 +5750,6 @@ const empty$14 = () => constEmpty;
5816
5750
  */
5817
5751
  const isEmptyRecord = (self) => Object.keys(self).length === 0;
5818
5752
  /**
5819
- * Takes a record and returns an array of tuples containing its keys and values.
5820
- *
5821
- * **Example** (Converting a record to entries)
5822
- *
5823
- * ```ts
5824
- * import { Record } from "effect"
5825
- * import * as assert from "node:assert"
5826
- *
5827
- * const x = { a: 1, b: 2, c: 3 }
5828
- * assert.deepStrictEqual(Record.toEntries(x), [["a", 1], ["b", 2], ["c", 3]])
5829
- * ```
5830
- *
5831
- * @category converting
5832
- * @since 2.0.0
5833
- */
5834
- const toEntries = /*#__PURE__*/ (/* @__PURE__ */ dual(2, (self, f) => {
5835
- const out = [];
5836
- for (const key of keys(self)) out.push(f(key, self[key]));
5837
- return out;
5838
- }))((key, value) => [key, value]);
5839
- /**
5840
5753
  * Checks whether a given `key` exists in a record.
5841
5754
  *
5842
5755
  * **Example** (Checking key membership)
@@ -6527,38 +6440,6 @@ const drop$1 = /*#__PURE__*/ dual(2, (self, n) => {
6527
6440
  */
6528
6441
  const reverse = (self) => Array$1.from(self).reverse();
6529
6442
  /**
6530
- * Sorts an array by the given `Order`, returning a new array.
6531
- *
6532
- * **When to use**
6533
- *
6534
- * Use to sort an array using a single `Order` comparator.
6535
- *
6536
- * **Details**
6537
- *
6538
- * - Preserves `NonEmptyArray` in the return type.
6539
- * - Use {@link sortWith} to sort by a derived key, or {@link sortBy} for
6540
- * multi-key sorting.
6541
- *
6542
- * **Example** (Sorting numbers)
6543
- *
6544
- * ```ts
6545
- * import { Array, Order } from "effect"
6546
- *
6547
- * console.log(Array.sort([3, 1, 4, 1, 5], Order.Number)) // [1, 1, 3, 4, 5]
6548
- * ```
6549
- *
6550
- * @see {@link sortWith} — sort by a mapping function
6551
- * @see {@link sortBy} — sort by multiple orders
6552
- *
6553
- * @category sorting
6554
- * @since 2.0.0
6555
- */
6556
- const sort = /*#__PURE__*/ dual(2, (self, O) => {
6557
- const out = Array$1.from(self);
6558
- out.sort(O);
6559
- return out;
6560
- });
6561
- /**
6562
6443
  * Sorts an array by a derived key using a mapping function and an `Order` for
6563
6444
  * that key.
6564
6445
  *
@@ -6793,6 +6674,28 @@ const flatMap$5 = /*#__PURE__*/ dual(2, (self, f) => {
6793
6674
  return out;
6794
6675
  });
6795
6676
  /**
6677
+ * Flattens a nested array of arrays into a single array.
6678
+ *
6679
+ * **When to use**
6680
+ *
6681
+ * Use to collapse one level of nested arrays when no per-element mapping is
6682
+ * needed.
6683
+ *
6684
+ * **Example** (Flattening nested arrays)
6685
+ *
6686
+ * ```ts
6687
+ * import { Array } from "effect"
6688
+ *
6689
+ * console.log(Array.flatten([[1, 2], [], [3, 4], [], [5, 6]])) // [1, 2, 3, 4, 5, 6]
6690
+ * ```
6691
+ *
6692
+ * @see {@link flatMap} — map then flatten in one step
6693
+ *
6694
+ * @category sequencing
6695
+ * @since 2.0.0
6696
+ */
6697
+ const flatten$3 = /*#__PURE__*/ flatMap$5(identity);
6698
+ /**
6796
6699
  * Extracts all `Some` values from an iterable of `Option`s, discarding `None`s.
6797
6700
  *
6798
6701
  * **When to use**
@@ -6849,43 +6752,6 @@ const getSuccesses = (self) => {
6849
6752
  return out;
6850
6753
  };
6851
6754
  /**
6852
- * Keeps transformed values for elements where a `Filter` succeeds.
6853
- *
6854
- * **When to use**
6855
- *
6856
- * Use to transform elements with a `Result`-returning filter while discarding
6857
- * failures.
6858
- *
6859
- * **Details**
6860
- *
6861
- * - The filter receives `(element, index)`.
6862
- * - Failures are discarded.
6863
- *
6864
- * **Example** (Filter and transform)
6865
- *
6866
- * ```ts
6867
- * import { Array, Result } from "effect"
6868
- *
6869
- * console.log(Array.filterMap([1, 2, 3, 4], (n) => n % 2 === 0 ? Result.succeed(n * 10) : Result.failVoid))
6870
- * // [20, 40]
6871
- * ```
6872
- *
6873
- * @see {@link filter} — keep original elements matching a predicate
6874
- * @see {@link partition} for keeping both failures and successes
6875
- *
6876
- * @category filtering
6877
- * @since 2.0.0
6878
- */
6879
- const filterMap$1 = /*#__PURE__*/ dual(2, (self, f) => {
6880
- const as = fromIterable$2(self);
6881
- const out = [];
6882
- for (let i = 0; i < as.length; i++) {
6883
- const result = f(as[i], i);
6884
- if (isSuccess$1(result)) out.push(result.success);
6885
- }
6886
- return out;
6887
- });
6888
- /**
6889
6755
  * Keeps only elements satisfying a predicate (or refinement).
6890
6756
  *
6891
6757
  * **When to use**
@@ -7041,30 +6907,6 @@ const dedupeWith = /*#__PURE__*/ dual(2, (self, isEquivalent) => {
7041
6907
  return [];
7042
6908
  });
7043
6909
  /**
7044
- * Removes duplicates using `Equal.equivalence()`, preserving the order of the
7045
- * first occurrence.
7046
- *
7047
- * **When to use**
7048
- *
7049
- * Use to remove repeated values from an iterable when Effect's default equality
7050
- * is the right comparison, preserving the first occurrence.
7051
- *
7052
- * **Example** (Removing duplicates)
7053
- *
7054
- * ```ts
7055
- * import { Array } from "effect"
7056
- *
7057
- * console.log(Array.dedupe([1, 2, 1, 3, 2, 4])) // [1, 2, 3, 4]
7058
- * ```
7059
- *
7060
- * @see {@link dedupeWith} — use custom equality
7061
- * @see {@link dedupeAdjacent} — only dedupes consecutive elements
7062
- *
7063
- * @category elements
7064
- * @since 2.0.0
7065
- */
7066
- const dedupe = (self) => dedupeWith(self, asEquivalence());
7067
- /**
7068
6910
  * Joins string elements with a separator.
7069
6911
  *
7070
6912
  * **Example** (Joining strings)
@@ -7080,7 +6922,7 @@ const dedupe = (self) => dedupeWith(self, asEquivalence());
7080
6922
  * @category folding
7081
6923
  * @since 2.0.0
7082
6924
  */
7083
- const join$3 = /*#__PURE__*/ dual(2, (self, sep) => fromIterable$2(self).join(sep));
6925
+ const join$2 = /*#__PURE__*/ dual(2, (self, sep) => fromIterable$2(self).join(sep));
7084
6926
  //#endregion
7085
6927
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Effectable.js
7086
6928
  /**
@@ -7217,7 +7059,7 @@ const ServiceProto = {
7217
7059
  }
7218
7060
  };
7219
7061
  const ReferenceTypeId = "~effect/Context/Reference";
7220
- const TypeId$49 = "~effect/Context";
7062
+ const TypeId$48 = "~effect/Context";
7221
7063
  /**
7222
7064
  * Creates a `Context` from an existing service map without validating or
7223
7065
  * copying it.
@@ -7252,7 +7094,7 @@ const makeUnsafe$8 = (mapUnsafe) => {
7252
7094
  };
7253
7095
  const Proto$15 = {
7254
7096
  ...PipeInspectableProto,
7255
- [TypeId$49]: { _Services: (_) => _ },
7097
+ [TypeId$48]: { _Services: (_) => _ },
7256
7098
  toJSON() {
7257
7099
  return {
7258
7100
  _id: "Context",
@@ -7304,7 +7146,7 @@ const Proto$15 = {
7304
7146
  * @category guards
7305
7147
  * @since 2.0.0
7306
7148
  */
7307
- const isContext = (u) => hasProperty(u, TypeId$49);
7149
+ const isContext = (u) => hasProperty(u, TypeId$48);
7308
7150
  /**
7309
7151
  * Checks whether the provided argument is a `Reference`.
7310
7152
  *
@@ -7808,7 +7650,7 @@ const withMapUnsafe = (self, f) => {
7808
7650
  const Reference = Service;
7809
7651
  //#endregion
7810
7652
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Duration.js
7811
- const TypeId$48 = "~effect/time/Duration";
7653
+ const TypeId$47 = "~effect/time/Duration";
7812
7654
  const bigint0$2 = /*#__PURE__*/ BigInt(0);
7813
7655
  const bigint1e3 = /*#__PURE__*/ BigInt(1e3);
7814
7656
  const bigint1e6 = /*#__PURE__*/ BigInt(1e6);
@@ -7867,7 +7709,7 @@ const fromInputUnsafe = (input) => {
7867
7709
  }
7868
7710
  case "object": {
7869
7711
  if (input === null) break;
7870
- if (TypeId$48 in input) return input;
7712
+ if (TypeId$47 in input) return input;
7871
7713
  if (Array.isArray(input)) {
7872
7714
  if (input.length !== 2 || !input.every(isNumber)) return invalid(input);
7873
7715
  if (Number.isNaN(input[0]) || Number.isNaN(input[1])) return zero$1;
@@ -7902,7 +7744,7 @@ const zeroDurationValue = {
7902
7744
  const infinityDurationValue = { _tag: "Infinity" };
7903
7745
  const negativeInfinityDurationValue = { _tag: "NegativeInfinity" };
7904
7746
  const DurationProto = {
7905
- [TypeId$48]: TypeId$48,
7747
+ [TypeId$47]: TypeId$47,
7906
7748
  [symbol$3]() {
7907
7749
  return structure(this.value);
7908
7750
  },
@@ -7980,7 +7822,7 @@ const make$61 = (input) => {
7980
7822
  * @category guards
7981
7823
  * @since 2.0.0
7982
7824
  */
7983
- const isDuration = (u) => hasProperty(u, TypeId$48);
7825
+ const isDuration = (u) => hasProperty(u, TypeId$47);
7984
7826
  /**
7985
7827
  * Checks whether a Duration is finite (not infinite).
7986
7828
  *
@@ -9829,7 +9671,7 @@ const provideServiceImpl = (self, service, implementation) => updateContext$1(se
9829
9671
  /** @internal */
9830
9672
  const when$1 = /*#__PURE__*/ dual(2, (self, condition) => flatMap$4(condition, (pass) => pass ? asSome$1(self) : succeedNone$1));
9831
9673
  /** @internal */
9832
- const forever$2 = /*#__PURE__*/ dual((args) => isEffect$1(args[0]), (self, options) => whileLoop$1({
9674
+ const forever$1 = /*#__PURE__*/ dual((args) => isEffect$1(args[0]), (self, options) => whileLoop$1({
9833
9675
  while: constTrue,
9834
9676
  body: constant(options?.disableYield ? self : flatMap$4(self, (_) => yieldNow$1)),
9835
9677
  step: constVoid
@@ -10857,7 +10699,7 @@ const reportCauseUnsafe = (fiber, cause, defectsOnly) => {
10857
10699
  };
10858
10700
  //#endregion
10859
10701
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Deferred.js
10860
- const TypeId$47 = "~effect/Deferred";
10702
+ const TypeId$46 = "~effect/Deferred";
10861
10703
  /**
10862
10704
  * Checks whether a value is a `Deferred`.
10863
10705
  *
@@ -10869,9 +10711,9 @@ const TypeId$47 = "~effect/Deferred";
10869
10711
  * @category guards
10870
10712
  * @since 4.0.0
10871
10713
  */
10872
- const isDeferred = (u) => hasProperty(u, TypeId$47);
10714
+ const isDeferred = (u) => hasProperty(u, TypeId$46);
10873
10715
  const DeferredProto = {
10874
- [TypeId$47]: {
10716
+ [TypeId$46]: {
10875
10717
  _A: identity,
10876
10718
  _E: identity
10877
10719
  },
@@ -11913,14 +11755,14 @@ const close = scopeClose;
11913
11755
  const closeUnsafe = scopeCloseUnsafe;
11914
11756
  //#endregion
11915
11757
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Layer.js
11916
- const TypeId$46 = "~effect/Layer";
11758
+ const TypeId$45 = "~effect/Layer";
11917
11759
  const MemoMapTypeId = "~effect/Layer/MemoMap";
11918
11760
  const memoMapReuse = (entry, scope) => {
11919
11761
  entry.observers++;
11920
11762
  return andThen$1(scopeAddFinalizerExit(scope, (exit) => entry.finalizer(exit)), entry.effect);
11921
11763
  };
11922
11764
  const LayerProto = {
11923
- [TypeId$46]: {
11765
+ [TypeId$45]: {
11924
11766
  _ROut: identity,
11925
11767
  _E: identity,
11926
11768
  _RIn: identity
@@ -13715,11 +13557,11 @@ const Clock = ClockRef;
13715
13557
  //#endregion
13716
13558
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/internal/dateTime.js
13717
13559
  /** @internal */
13718
- const TypeId$45 = "~effect/time/DateTime";
13560
+ const TypeId$44 = "~effect/time/DateTime";
13719
13561
  /** @internal */
13720
13562
  const TimeZoneTypeId = "~effect/time/DateTime/TimeZone";
13721
13563
  const Proto$14 = {
13722
- [TypeId$45]: TypeId$45,
13564
+ [TypeId$44]: TypeId$44,
13723
13565
  pipe() {
13724
13566
  return pipeArguments(this, arguments);
13725
13567
  },
@@ -13982,76 +13824,6 @@ const endsWith = (searchString, position) => (self) => self.endsWith(searchStrin
13982
13824
  * @since 2.0.0
13983
13825
  */
13984
13826
  const replaceAll = (searchValue, replaceValue) => (self) => self.replaceAll(searchValue, replaceValue);
13985
- const CR = 13;
13986
- const LF = 10;
13987
- /**
13988
- * Returns an `IterableIterator` which yields each line contained within the
13989
- * string, trimming off the trailing newline character.
13990
- *
13991
- * **Example** (Iterating lines without separators)
13992
- *
13993
- * ```ts
13994
- * import { String } from "effect"
13995
- *
13996
- * const lines = String.linesIterator("hello\nworld\n")
13997
- * console.log(Array.from(lines)) // ["hello", "world"]
13998
- * ```
13999
- *
14000
- * @category splitting
14001
- * @since 2.0.0
14002
- */
14003
- const linesIterator = (self) => linesSeparated(self, true);
14004
- var LinesIterator = class LinesIterator {
14005
- index;
14006
- length;
14007
- s;
14008
- stripped;
14009
- constructor(s, stripped = false) {
14010
- this.s = s;
14011
- this.stripped = stripped;
14012
- this.index = 0;
14013
- this.length = s.length;
14014
- }
14015
- next() {
14016
- if (this.done) return {
14017
- done: true,
14018
- value: void 0
14019
- };
14020
- const start = this.index;
14021
- while (!this.done && !isLineBreak(this.s[this.index])) this.index = this.index + 1;
14022
- let end = this.index;
14023
- if (!this.done) {
14024
- const char = this.s[this.index];
14025
- this.index = this.index + 1;
14026
- if (!this.done && isLineBreak2(char, this.s[this.index])) this.index = this.index + 1;
14027
- if (!this.stripped) end = this.index;
14028
- }
14029
- return {
14030
- done: false,
14031
- value: this.s.substring(start, end)
14032
- };
14033
- }
14034
- [Symbol.iterator]() {
14035
- return new LinesIterator(this.s, this.stripped);
14036
- }
14037
- get done() {
14038
- return this.index >= this.length;
14039
- }
14040
- };
14041
- /**
14042
- * Checks whether the provided character is a line break character (i.e. either `"\r"`
14043
- * or `"\n"`).
14044
- */
14045
- const isLineBreak = (char) => {
14046
- const code = char.charCodeAt(0);
14047
- return code === CR || code === LF;
14048
- };
14049
- /**
14050
- * Checks whether the provided characters combine to form a carriage return/line-feed
14051
- * (i.e. `"\r\n"`).
14052
- */
14053
- const isLineBreak2 = (char0, char1) => char0.charCodeAt(0) === CR && char1.charCodeAt(0) === LF;
14054
- const linesSeparated = (self, stripped) => new LinesIterator(self, stripped);
14055
13827
  //#endregion
14056
13828
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/internal/random.js
14057
13829
  /** @internal */
@@ -14234,434 +14006,10 @@ const matchEffect$1 = /*#__PURE__*/ dual(2, (self, options) => matchCauseEffect$
14234
14006
  }
14235
14007
  }));
14236
14008
  //#endregion
14237
- //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/Schedule.js
14238
- /**
14239
- * Declarative policies for retrying, repeating, and pacing Effect programs.
14240
- *
14241
- * A `Schedule<Output, Input, Error, Env>` is a stateful policy that is stepped
14242
- * with an input value. Each step either stops the recurrence or emits an output
14243
- * together with the delay before the next step. Schedules are values: they can
14244
- * be transformed, combined, and passed to retry, repeat, stream, and channel
14245
- * APIs without running anything until the surrounding Effect program runs.
14246
- *
14247
- * **Mental model**
14248
- *
14249
- * - Constructors such as {@link recurs}, {@link spaced}, {@link fixed},
14250
- * {@link exponential}, and {@link fibonacci} define the base cadence or
14251
- * stopping rule.
14252
- * - Combinators such as {@link both}, {@link either}, and {@link andThen}
14253
- * combine schedules and determine both stopping behavior and output shape.
14254
- * - Delay helpers such as {@link addDelay}, {@link modifyDelay}, and
14255
- * {@link jittered} adjust pacing while preserving the schedule's control
14256
- * flow.
14257
- * - Metadata-aware constructors and {@link CurrentMetadata} expose attempts,
14258
- * elapsed time, input, output, and duration for advanced policies.
14259
- *
14260
- * **Common tasks**
14261
- *
14262
- * - Retry a failing effect with exponential backoff and a maximum retry count.
14263
- * - Repeat a successful effect on a fixed or spaced interval.
14264
- * - Add jitter so concurrent clients do not retry at the same instant.
14265
- * - Transform or retain schedule outputs with {@link map},
14266
- * {@link collectOutputs}, and {@link take}.
14267
- *
14268
- * **Example** (Retrying with bounded exponential backoff)
14269
- *
14270
- * ```ts
14271
- * import { Effect, Schedule } from "effect"
14272
- *
14273
- * let attempts = 0
14274
- *
14275
- * const request = Effect.sync(() => {
14276
- * attempts += 1
14277
- * return attempts
14278
- * }).pipe(
14279
- * Effect.flatMap((attempt) =>
14280
- * attempt < 3 ? Effect.fail("temporary failure") : Effect.succeed("ok")
14281
- * )
14282
- * )
14283
- *
14284
- * const policy = Schedule.exponential("100 millis").pipe(
14285
- * Schedule.jittered,
14286
- * Schedule.both(Schedule.recurs(5))
14287
- * )
14288
- *
14289
- * const program = Effect.retry(request, policy)
14290
- * ```
14291
- *
14292
- * **Gotchas**
14293
- *
14294
- * - A schedule is a description; delays happen only when an operation such as
14295
- * `Effect.retry` or `Effect.repeat` runs it.
14296
- * - `Schedule.recurs(3)` allows three recurrences in addition to the first run
14297
- * performed by retry or repeat.
14298
- * - Combining schedules changes the output type as well as the stopping rule,
14299
- * so check the resulting type when using {@link both}, {@link either}, or
14300
- * {@link andThen}.
14301
- *
14302
- * @since 2.0.0
14303
- */
14304
- const TypeId$44 = "~effect/Schedule";
14305
- /**
14306
- * Context reference containing metadata for the currently running schedule step.
14307
- *
14308
- * **Details**
14309
- *
14310
- * Repeat, retry, stream, and channel scheduling operations provide this service
14311
- * to effects run between schedule steps. The default value contains undefined
14312
- * input and output values, zero duration, and zeroed timing fields before any
14313
- * schedule step has produced metadata.
14314
- *
14315
- * @category metadata
14316
- * @since 4.0.0
14317
- */
14318
- const CurrentMetadata = /*#__PURE__*/ Reference("effect/Schedule/CurrentMetadata", { defaultValue: /*#__PURE__*/ constant({
14319
- input: void 0,
14320
- output: void 0,
14321
- duration: zero$1,
14322
- attempt: 0,
14323
- start: 0,
14324
- now: 0,
14325
- elapsed: 0,
14326
- elapsedSincePrevious: 0
14327
- }) });
14328
- const ScheduleProto = {
14329
- [TypeId$44]: {
14330
- _Out: identity,
14331
- _In: identity,
14332
- _Env: identity
14333
- },
14334
- pipe() {
14335
- return pipeArguments(this, arguments);
14336
- }
14337
- };
14338
- /**
14339
- * Type guard that checks if a value is a Schedule.
14340
- *
14341
- * **Example** (Checking for schedules)
14342
- *
14343
- * ```ts
14344
- * import { Schedule } from "effect"
14345
- *
14346
- * const schedule = Schedule.exponential("100 millis")
14347
- * const notSchedule = { foo: "bar" }
14348
- *
14349
- * console.log(Schedule.isSchedule(schedule)) // true
14350
- * console.log(Schedule.isSchedule(notSchedule)) // false
14351
- * console.log(Schedule.isSchedule(null)) // false
14352
- * console.log(Schedule.isSchedule(undefined)) // false
14353
- * ```
14354
- *
14355
- * @category guards
14356
- * @since 2.0.0
14357
- */
14358
- const isSchedule = (u) => hasProperty(u, TypeId$44);
14359
- /**
14360
- * Creates a Schedule from a step function that returns a Pull.
14361
- *
14362
- * **Example** (Creating a custom schedule from a step function)
14363
- *
14364
- * ```ts
14365
- * import { Cause, Duration, Effect, Schedule } from "effect"
14366
- *
14367
- * const schedule = Schedule.fromStep(Effect.sync(() => {
14368
- * let count = 0
14369
- *
14370
- * return (_now: number, _input: string) => {
14371
- * if (count >= 3) {
14372
- * return Cause.done(count)
14373
- * }
14374
- * return Effect.succeed([count++, Duration.millis(100)] as [number, Duration.Duration])
14375
- * }
14376
- * }))
14377
- * ```
14378
- *
14379
- * @category constructors
14380
- * @since 4.0.0
14381
- */
14382
- const fromStep = (step) => {
14383
- const self = Object.create(ScheduleProto);
14384
- self.step = step;
14385
- return self;
14386
- };
14387
- const metadataFn = () => {
14388
- let n = 0;
14389
- let previous;
14390
- let start;
14391
- return (now, input) => {
14392
- if (start === void 0) start = now;
14393
- const elapsed = now - start;
14394
- const elapsedSincePrevious = previous === void 0 ? 0 : now - previous;
14395
- previous = now;
14396
- return {
14397
- input,
14398
- attempt: ++n,
14399
- start,
14400
- now,
14401
- elapsed,
14402
- elapsedSincePrevious
14403
- };
14404
- };
14405
- };
14406
- /**
14407
- * Creates a Schedule from a step function that receives metadata about the schedule's execution.
14408
- *
14409
- * **Example** (Creating a metadata-aware schedule)
14410
- *
14411
- * ```ts
14412
- * import { Cause, Duration, Effect, Schedule } from "effect"
14413
- *
14414
- * const firstThreeInputs = Schedule.fromStepWithMetadata(Effect.succeed((metadata: Schedule.InputMetadata<string>) => {
14415
- * if (metadata.attempt > 3) {
14416
- * return Cause.done("finished")
14417
- * }
14418
- *
14419
- * return Effect.succeed([
14420
- * `attempt ${metadata.attempt}: ${metadata.input}`,
14421
- * Duration.millis(250)
14422
- * ] as [string, Duration.Duration])
14423
- * }))
14424
- * ```
14425
- *
14426
- * @category constructors
14427
- * @since 4.0.0
14428
- */
14429
- const fromStepWithMetadata = (step) => fromStep(map$6(step, (f) => {
14430
- const meta = metadataFn();
14431
- return (now, input) => f(meta(now, input));
14432
- }));
14433
- /**
14434
- * Extracts the step function from a Schedule.
14435
- *
14436
- * **Example** (Extracting a schedule step function)
14437
- *
14438
- * ```ts
14439
- * import { Effect, Schedule } from "effect"
14440
- *
14441
- * // Extract step function from an existing schedule
14442
- * const schedule = Schedule.exponential("100 millis").pipe(Schedule.take(3))
14443
- *
14444
- * const program = Effect.gen(function*() {
14445
- * const stepFn = yield* Schedule.toStep(schedule)
14446
- *
14447
- * // Use the step function directly for custom logic. The timestamp is
14448
- * // supplied by the caller, so tests can pass a deterministic value.
14449
- * const now = 0
14450
- * const result = yield* stepFn(now, "input")
14451
- *
14452
- * console.log(`Step result: ${result}`)
14453
- * })
14454
- * ```
14455
- *
14456
- * @category destructors
14457
- * @since 4.0.0
14458
- */
14459
- const toStep = (schedule) => catchCause$2(schedule.step, (cause) => succeed$6(() => failCause$5(cause)));
14460
- /**
14461
- * Extracts a step function from a `Schedule` that sleeps for each computed
14462
- * delay and returns metadata for the completed step.
14463
- *
14464
- * **When to use**
14465
- *
14466
- * Use to drive a schedule manually while preserving the computed output,
14467
- * delay, input, attempt, and elapsed timing metadata for each step.
14468
- *
14469
- * **Details**
14470
- *
14471
- * The returned step reads the current time from `Clock` when invoked, calls the
14472
- * schedule step with that timestamp and input, sleeps for the returned
14473
- * duration, and then yields `Metadata`.
14474
- *
14475
- * @see {@link toStep} for manually supplying the timestamp and handling the returned delay yourself
14476
- * @see {@link toStepWithSleep} for the same automatic sleeping behavior when only the schedule output is needed
14477
- *
14478
- * @category destructors
14479
- * @since 4.0.0
14480
- */
14481
- const toStepWithMetadata = (schedule) => clockWith$1((clock) => map$6(toStep(schedule), (step) => {
14482
- const metaFn = metadataFn();
14483
- return (input) => suspend$3(() => {
14484
- const now = clock.currentTimeMillisUnsafe();
14485
- return flatMap$4(step(now, input), ([output, duration]) => {
14486
- const meta = metaFn(now, input);
14487
- meta.output = output;
14488
- meta.duration = duration;
14489
- return as$1(sleep$1(duration), meta);
14490
- });
14491
- });
14492
- }));
14493
- /**
14494
- * Returns a new `Schedule` that outputs the inputs of the specified schedule.
14495
- *
14496
- * **Example** (Passing inputs through as outputs)
14497
- *
14498
- * ```ts
14499
- * import { Console, Effect, Schedule } from "effect"
14500
- *
14501
- * // Create a schedule that outputs the inputs instead of original outputs
14502
- * const inputSchedule = Schedule.passthrough(
14503
- * Schedule.exponential("100 millis").pipe(Schedule.take(3))
14504
- * )
14505
- *
14506
- * const program = Effect.gen(function*() {
14507
- * let counter = 0
14508
- * yield* Effect.repeat(
14509
- * Effect.gen(function*() {
14510
- * counter++
14511
- * yield* Console.log(`Task ${counter} executed`)
14512
- * return `result-${counter}`
14513
- * }),
14514
- * inputSchedule
14515
- * )
14516
- * })
14517
- * ```
14518
- *
14519
- * @category mapping
14520
- * @since 2.0.0
14521
- */
14522
- const passthrough$2 = (self) => fromStep(map$6(toStep(self), (step) => (now, input) => matchEffect$1(step(now, input), {
14523
- onSuccess: (result) => succeed$6([input, result[1]]),
14524
- onFailure: failCause$5,
14525
- onDone: () => done(input)
14526
- })));
14527
- /**
14528
- * Returns a schedule that recurs continuously, each repetition spaced the
14529
- * specified duration from the last run.
14530
- *
14531
- * **When to use**
14532
- *
14533
- * Use when each delay should start after the previous action
14534
- * completes. Use `fixed` when recurrences should stay aligned to a regular
14535
- * cadence.
14536
- *
14537
- * **Example** (Repeating with fixed spacing)
14538
- *
14539
- * ```ts
14540
- * import { Console, Effect, Schedule } from "effect"
14541
- *
14542
- * // Basic spaced schedule - runs every 2 seconds
14543
- * const everyTwoSeconds = Schedule.spaced("2 seconds")
14544
- *
14545
- * // Heartbeat that runs indefinitely with fixed spacing
14546
- * const heartbeat = Effect.gen(function*() {
14547
- * yield* Console.log("Heartbeat")
14548
- * }).pipe(
14549
- * Effect.repeat(everyTwoSeconds)
14550
- * )
14551
- *
14552
- * // Limited repeat - run only 5 times with 1-second spacing
14553
- * const limitedTask = Effect.gen(function*() {
14554
- * yield* Console.log("Executing scheduled task...")
14555
- * yield* Effect.sleep("500 millis") // simulate work
14556
- * return "Task completed"
14557
- * }).pipe(
14558
- * Effect.repeat(
14559
- * Schedule.spaced("1 second").pipe(Schedule.take(5))
14560
- * )
14561
- * )
14562
- *
14563
- * // Simple spaced schedule with limited repetitions
14564
- * const limitedSpaced = Schedule.spaced("100 millis").pipe(
14565
- * Schedule.both(Schedule.recurs(5)) // at most 5 times
14566
- * )
14567
- *
14568
- * const program = Effect.gen(function*() {
14569
- * yield* Console.log("Starting spaced execution...")
14570
- *
14571
- * yield* Effect.repeat(
14572
- * Effect.succeed("work item"),
14573
- * limitedSpaced
14574
- * )
14575
- *
14576
- * yield* Console.log("Completed executions")
14577
- * })
14578
- * ```
14579
- *
14580
- * @see {@link fixed} for recurrence aligned to a regular cadence
14581
- *
14582
- * @category constructors
14583
- * @since 2.0.0
14584
- */
14585
- const spaced = (duration) => {
14586
- const decoded = fromInputUnsafe(duration);
14587
- return fromStepWithMetadata(succeed$6((meta) => succeed$6([meta.attempt - 1, decoded])));
14588
- };
14589
- const while_ = /*#__PURE__*/ dual(2, (self, predicate) => fromStep(map$6(toStep(self), (step) => {
14590
- const meta = metadataFn();
14591
- return (now, input) => flatMap$4(step(now, input), (result) => {
14592
- const [output, duration] = result;
14593
- const eff = predicate({
14594
- ...meta(now, input),
14595
- output,
14596
- duration
14597
- });
14598
- return flatMap$4(isEffect$1(eff) ? eff : succeed$6(eff), (check) => check ? succeed$6(result) : done(output));
14599
- });
14600
- })));
14601
- /**
14602
- * Returns a new `Schedule` that will recur forever.
14603
- *
14604
- * **Details**
14605
- *
14606
- * The output of the schedule is the current count of its repetitions thus far
14607
- * (i.e. `0, 1, 2, ...`).
14608
- *
14609
- * **Example** (Repeating forever)
14610
- *
14611
- * ```ts
14612
- * import { Console, Effect, Schedule } from "effect"
14613
- *
14614
- * // A schedule that runs forever with no delay
14615
- * const infiniteSchedule = Schedule.forever
14616
- *
14617
- * const program = Effect.gen(function*() {
14618
- * yield* Effect.repeat(
14619
- * Effect.gen(function*() {
14620
- * yield* Console.log("Running forever...")
14621
- * return "continuous-task"
14622
- * }),
14623
- * infiniteSchedule.pipe(Schedule.take(5)) // Limit for demo
14624
- * )
14625
- * })
14626
- * ```
14627
- *
14628
- * @category constructors
14629
- * @since 2.0.0
14630
- */
14631
- const forever$1 = /*#__PURE__*/ spaced(zero$1);
14632
- //#endregion
14633
14009
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/internal/layer.js
14634
14010
  const provideLayer = (self, layer, options) => scopedWith$1((scope) => flatMap$4(options?.local ? buildWithMemoMap(layer, makeMemoMapUnsafe(), scope) : buildWithScope(layer, scope), (context) => provideContext$3(self, context)));
14635
14011
  /** @internal */
14636
14012
  const provide$1 = /*#__PURE__*/ dual((args) => isEffect$1(args[0]), (self, source, options) => isContext(source) ? provideContext$3(self, source) : provideLayer(self, Array.isArray(source) ? mergeAll$1(...source) : source, options));
14637
- //#endregion
14638
- //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/internal/schedule.js
14639
- /** @internal */
14640
- const repeatOrElse = /*#__PURE__*/ dual(3, (self, schedule, orElse) => flatMap$4(toStepWithMetadata(schedule), (step) => {
14641
- let meta = CurrentMetadata.defaultValue();
14642
- return catch_$3(forever$2(tap$1(flatMap$4(suspend$3(() => provideService$1(self, CurrentMetadata, meta)), step), (meta_) => sync$1(() => {
14643
- meta = meta_;
14644
- })), { disableYield: true }), (error) => isDone$2(error) ? succeed$6(error.value) : orElse(error, meta.attempt === 0 ? none() : some$1(meta)));
14645
- }));
14646
- /** @internal */
14647
- const repeat$1 = /*#__PURE__*/ dual(2, (self, options) => {
14648
- return repeatOrElse(self, typeof options === "function" ? options(identity) : isSchedule(options) ? options : buildFromOptions(options), fail$6);
14649
- });
14650
- const passthroughForever = /*#__PURE__*/ passthrough$2(forever$1);
14651
- /** @internal */
14652
- const buildFromOptions = (options) => {
14653
- let schedule = options.schedule ? passthrough$2(options.schedule) : passthroughForever;
14654
- if (options.while) schedule = while_(schedule, ({ input }) => {
14655
- const applied = options.while(input);
14656
- return isEffect$1(applied) ? applied : succeed$6(applied);
14657
- });
14658
- if (options.until) schedule = while_(schedule, ({ input }) => {
14659
- const applied = options.until(input);
14660
- return isEffect$1(applied) ? map$6(applied, (b) => !b) : succeed$6(!applied);
14661
- });
14662
- if (options.times !== void 0) schedule = while_(schedule, ({ attempt }) => succeed$6(attempt <= options.times));
14663
- return schedule;
14664
- };
14665
14013
  /**
14666
14014
  * Context reference for the metric registry in the current context.
14667
14015
  *
@@ -17772,84 +17120,7 @@ const interruptibleMask = interruptibleMask$1;
17772
17120
  * @category repetition
17773
17121
  * @since 2.0.0
17774
17122
  */
17775
- const forever = forever$2;
17776
- /**
17777
- * Repeats an effect based on a specified schedule or until the first failure.
17778
- *
17779
- * **When to use**
17780
- *
17781
- * Use to rerun an effect after successful executions.
17782
- *
17783
- * **Details**
17784
- *
17785
- * This function executes an effect repeatedly according to the given schedule.
17786
- * Each repetition occurs after the initial execution of the effect, meaning
17787
- * that the schedule determines the number of additional repetitions. For
17788
- * example, using `Schedule.once` will result in the effect being executed twice
17789
- * (once initially and once as part of the repetition).
17790
- *
17791
- * If the effect succeeds, it is repeated according to the schedule. If it
17792
- * fails, the repetition stops immediately, and the failure is returned.
17793
- *
17794
- * The schedule can also specify delays between repetitions, making it useful
17795
- * for tasks like retrying operations with backoff, periodic execution, or
17796
- * performing a series of dependent actions.
17797
- *
17798
- * You can combine schedules for more advanced repetition logic, such as adding
17799
- * delays, limiting recursions, or dynamically adjusting based on the outcome of
17800
- * each execution.
17801
- *
17802
- * **Gotchas**
17803
- *
17804
- * The source effect is always evaluated once before the schedule is stepped.
17805
- * The schedule controls additional repetitions, not the initial execution.
17806
- *
17807
- * **Example** (Repeating successful effects with a schedule)
17808
- *
17809
- * ```ts
17810
- * // Success Example
17811
- * import { Console, Effect, Schedule } from "effect"
17812
- *
17813
- * const action = Console.log("success")
17814
- * const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))
17815
- * const program = Effect.repeat(action, policy)
17816
- *
17817
- * // Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
17818
- * ```
17819
- *
17820
- * **Example** (Stopping repetition on failure)
17821
- *
17822
- * ```ts
17823
- * // Failure Example
17824
- * import { Effect, Schedule } from "effect"
17825
- *
17826
- * let count = 0
17827
- *
17828
- * // Define a callback effect that simulates an action with possible failures
17829
- * const action = Effect.callback<string, string>((resume) => {
17830
- * if (count > 1) {
17831
- * console.log("failure")
17832
- * resume(Effect.fail("Uh oh!"))
17833
- * } else {
17834
- * count++
17835
- * console.log("success")
17836
- * resume(Effect.succeed("yay!"))
17837
- * }
17838
- * })
17839
- *
17840
- * const policy = Schedule.addDelay(Schedule.recurs(2), () => Effect.succeed("100 millis"))
17841
- * const program = Effect.repeat(action, policy)
17842
- *
17843
- * // Effect.runPromiseExit(program).then(console.log)
17844
- * ```
17845
- *
17846
- * @see {@link retry} for failure-based repetition
17847
- * @see {@link repeatOrElse} for fallback handling when repetition fails
17848
- *
17849
- * @category repetition
17850
- * @since 2.0.0
17851
- */
17852
- const repeat = repeat$1;
17123
+ const forever = forever$1;
17853
17124
  /**
17854
17125
  * Create a new span for tracing, and automatically close it when the effect
17855
17126
  * completes.
@@ -20394,7 +19665,7 @@ const abs = (n) => n.value < bigint0 ? make$54(-n.value, n.scale) : n;
20394
19665
  * @category instances
20395
19666
  * @since 2.0.0
20396
19667
  */
20397
- const Equivalence$2 = /*#__PURE__*/ make$65((self, that) => {
19668
+ const Equivalence$2 = /*#__PURE__*/ make$64((self, that) => {
20398
19669
  if (self.scale > that.scale) return scale(that, self.scale).value === self.value;
20399
19670
  if (self.scale < that.scale) return scale(self, that.scale).value === that.value;
20400
19671
  return self.value === that.value;
@@ -22981,7 +22252,7 @@ const badArgument = (options) => new PlatformError(new BadArgument(options));
22981
22252
  * @category combinators
22982
22253
  * @since 2.0.0
22983
22254
  */
22984
- const join$2 = fiberJoin;
22255
+ const join$1 = fiberJoin;
22985
22256
  /**
22986
22257
  * Interrupts a fiber, causing it to stop executing and clean up any
22987
22258
  * acquired resources.
@@ -27190,7 +26461,7 @@ const mapEffectConcurrent = (self, f, options) => fromTransformBracket(fnUntrace
27190
26461
  const fiber = runFork(f(value, i++));
27191
26462
  trackFiber(fiber);
27192
26463
  fiber.addObserver(onExit);
27193
- return offer(effects, join$2(fiber));
26464
+ return offer(effects, join$1(fiber));
27194
26465
  }), forever({ disableYield: true }), catchCause$1((cause) => offer(effects, failCause$3(cause)).pipe(andThen(failCause$1(effects, cause)))), forkIn(forkedScope));
27195
26466
  }
27196
26467
  return take$1(queue);
@@ -32952,29 +32223,6 @@ function decodeUnknownEffect$1(schema, options) {
32952
32223
  return options === void 0 ? parser : (input, overrideOptions) => parser(input, mergeParseOptions(options, overrideOptions));
32953
32224
  }
32954
32225
  /**
32955
- * Creates a synchronous decoder for `unknown` input.
32956
- *
32957
- * **When to use**
32958
- *
32959
- * Use to decode untrusted or dynamically typed input at a synchronous boundary
32960
- * where invalid data should be reported by throwing.
32961
- *
32962
- * **Details**
32963
- *
32964
- * The returned function returns the decoded `Type` on success and throws an
32965
- * `Error` with the `SchemaIssue.Issue` in its `cause` on decoding failure.
32966
- *
32967
- * @see {@link decodeSync} for input already typed as the schema's `Encoded` type
32968
- * @see {@link decodeUnknownEffect} for preserving decoding failures in `Effect`
32969
- * @see {@link decodeUnknownResult} for returning schema issues as data
32970
- *
32971
- * @category decoding
32972
- * @since 3.10.0
32973
- */
32974
- function decodeUnknownSync$1(schema, options) {
32975
- return asSync(decodeUnknownEffect$1(schema, options));
32976
- }
32977
- /**
32978
32226
  * Creates an effectful encoder for `unknown` input.
32979
32227
  *
32980
32228
  * **When to use**
@@ -33349,44 +32597,6 @@ function decodeUnknownEffect(schema, options) {
33349
32597
  */
33350
32598
  const decodeEffect = decodeUnknownEffect;
33351
32599
  /**
33352
- * Decodes an `unknown` input against a schema synchronously, returning the
33353
- * decoded value or throwing an `Error` whose cause contains the schema issue.
33354
- *
33355
- * **When to use**
33356
- *
33357
- * Use when validating unknown data at a boundary and treating schema mismatches
33358
- * as exceptions.
33359
- *
33360
- * **Details**
33361
- *
33362
- * For typed input use `decodeSync`.
33363
- * Only service-free schemas can be decoded synchronously. For non-throwing
33364
- * alternatives see `decodeUnknownOption`, `decodeUnknownExit`, or
33365
- * `decodeUnknownEffect`. Options may be provided either when creating the
33366
- * decoder or when applying it; application options override creation options.
33367
- *
33368
- * **Example** (Decoding with a transformation schema)
33369
- *
33370
- * ```ts
33371
- * import { Schema } from "effect"
33372
- *
33373
- * const NumberFromString = Schema.NumberFromString
33374
- *
33375
- * console.log(Schema.decodeUnknownSync(NumberFromString)("42"))
33376
- * // Output: 42
33377
- *
33378
- * Schema.decodeUnknownSync(NumberFromString)("not a number")
33379
- * // throws SchemaError: NumberFromString
33380
- * // └─ Encoded side transformation failure
33381
- * // └─ NumberFromString
33382
- * // └─ Expected a numeric string, actual "not a number"
33383
- * ```
33384
- *
33385
- * @category decoding
33386
- * @since 4.0.0
33387
- */
33388
- const decodeUnknownSync = decodeUnknownSync$1;
33389
- /**
33390
32600
  * Encodes an `unknown` input against a schema, returning an `Effect` that
33391
32601
  * succeeds with the encoded value or fails with a {@link SchemaError}.
33392
32602
  *
@@ -35731,7 +34941,7 @@ const fromInputNested = (input) => {
35731
34941
  * @category instances
35732
34942
  * @since 4.0.0
35733
34943
  */
35734
- const Equivalence = /*#__PURE__*/ make$65((a, b) => arrayEquivalence(a.params, b.params));
34944
+ const Equivalence = /*#__PURE__*/ make$64((a, b) => arrayEquivalence(a.params, b.params));
35735
34945
  const arrayEquivalence = /*#__PURE__*/ makeEquivalence(/*#__PURE__*/ makeEquivalence$2([/*#__PURE__*/ strictEqual(), /*#__PURE__*/ strictEqual()]));
35736
34946
  /**
35737
34947
  * An empty `UrlParams` value.
@@ -38299,7 +37509,7 @@ const runtime = (self) => () => map$4(context$1(), (services) => {
38299
37509
  * @category combinators
38300
37510
  * @since 2.0.0
38301
37511
  */
38302
- const join$1 = (self) => _await(self.deferred);
37512
+ const join = (self) => _await(self.deferred);
38303
37513
  //#endregion
38304
37514
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/unstable/socket/Socket.js
38305
37515
  /**
@@ -38339,6 +37549,36 @@ const encoder = /*#__PURE__*/ new TextEncoder();
38339
37549
  const decoder$1 = /*#__PURE__*/ new TextDecoder();
38340
37550
  const CloseEventTypeId = "~effect/socket/Socket/CloseEvent";
38341
37551
  /**
37552
+ * Represents a socket close event value carrying a close code and optional
37553
+ * reason.
37554
+ *
37555
+ * @category models
37556
+ * @since 4.0.0
37557
+ */
37558
+ var CloseEvent = class {
37559
+ /**
37560
+ * Marks this value as a socket close event for runtime guards.
37561
+ *
37562
+ * @since 4.0.0
37563
+ */
37564
+ [CloseEventTypeId];
37565
+ code;
37566
+ reason;
37567
+ constructor(code = 1e3, reason) {
37568
+ this[CloseEventTypeId] = CloseEventTypeId;
37569
+ this.code = code;
37570
+ this.reason = reason;
37571
+ }
37572
+ /**
37573
+ * Formats the close code and optional reason for display.
37574
+ *
37575
+ * @since 4.0.0
37576
+ */
37577
+ toString() {
37578
+ return this.reason ? `${this.code}: ${this.reason}` : `${this.code}`;
37579
+ }
37580
+ };
37581
+ /**
38342
37582
  * Returns `true` when a value is a `CloseEvent`.
38343
37583
  *
38344
37584
  * @category refinements
@@ -38585,13 +37825,13 @@ const fromWebSocket = (acquire, options) => withFiber((fiber) => {
38585
37825
  kind: "Timeout",
38586
37826
  cause: /* @__PURE__ */ new Error("timeout waiting for \"open\"")
38587
37827
  }) }))
38588
- }), raceFirst(join$1(fiberSet)));
37828
+ }), raceFirst(join(fiberSet)));
38589
37829
  }
38590
37830
  open = true;
38591
37831
  currentWS = ws;
38592
37832
  latch.openUnsafe();
38593
37833
  if (opts?.onOpen) yield* opts.onOpen;
38594
- return yield* catchFilter(join$1(fiberSet), SocketCloseError.filterClean((_) => !closeCodeIsError(_)), () => void_$1);
37834
+ return yield* catchFilter(join(fiberSet), SocketCloseError.filterClean((_) => !closeCodeIsError(_)), () => void_$1);
38595
37835
  })).pipe(updateContext((input) => merge$3(acquireContext, input)), ensuring$2(sync(() => {
38596
37836
  latch.closeUnsafe();
38597
37837
  currentWS = void 0;
@@ -49260,7 +48500,7 @@ const readDirectory = (path, options) => tryPromise({
49260
48500
  try: () => NFS.promises.readdir(path, options),
49261
48501
  catch: (err) => handleErrnoException("FileSystem", "readDirectory")(err, [path])
49262
48502
  });
49263
- const readFile$1 = (path) => callback$1((resume, signal) => {
48503
+ const readFile = (path) => callback$1((resume, signal) => {
49264
48504
  try {
49265
48505
  NFS.readFile(path, { signal }, (err, data) => {
49266
48506
  if (err) resume(fail$3(handleErrnoException("FileSystem", "readFile")(err, [path])));
@@ -49381,7 +48621,7 @@ const makeFileSystem = /*#__PURE__*/ map$4(/*#__PURE__*/ serviceOption(WatchBack
49381
48621
  makeTempFileScoped,
49382
48622
  open,
49383
48623
  readDirectory,
49384
- readFile: readFile$1,
48624
+ readFile,
49385
48625
  readLink,
49386
48626
  realPath,
49387
48627
  remove,
@@ -51856,37 +51096,6 @@ const set = /*#__PURE__*/ dual(2, (self, value) => self.semaphore.withPermit(syn
51856
51096
  * @since 2.0.0
51857
51097
  */
51858
51098
  const update = /*#__PURE__*/ dual(2, (self, update) => self.semaphore.withPermit(sync(() => setUnsafe(self, update(self.value)))));
51859
- /**
51860
- * Applies an update function to the current value. If it returns
51861
- * `Option.some`, sets and publishes that value; if it returns `Option.none`,
51862
- * leaves the reference unchanged and does not publish.
51863
- *
51864
- * **Example** (Conditionally updating a value)
51865
- *
51866
- * ```ts
51867
- * import { Effect, Option, SubscriptionRef } from "effect"
51868
- *
51869
- * const program = Effect.gen(function*() {
51870
- * const ref = yield* SubscriptionRef.make(10)
51871
- *
51872
- * yield* SubscriptionRef.updateSome(
51873
- * ref,
51874
- * (n) => n > 5 ? Option.some(n * 2) : Option.none()
51875
- * )
51876
- *
51877
- * const value = yield* SubscriptionRef.get(ref)
51878
- * console.log(value)
51879
- * })
51880
- * ```
51881
- *
51882
- * @category updating
51883
- * @since 2.0.0
51884
- */
51885
- const updateSome = /*#__PURE__*/ dual(2, (self, update) => self.semaphore.withPermit(sync(() => {
51886
- const option = update(self.value);
51887
- if (isNone(option)) return;
51888
- setUnsafe(self, option.value);
51889
- })));
51890
51099
  //#endregion
51891
51100
  //#region ../../node_modules/.pnpm/effect@4.0.0-beta.74/node_modules/effect/dist/unstable/http/HttpStaticServer.js
51892
51101
  /**
@@ -52299,7 +51508,6 @@ Union([
52299
51508
  Struct({ type: Literal("stop") })
52300
51509
  ]);
52301
51510
  const TerminalState = Struct({
52302
- ports: ArraySchema(Number$1),
52303
51511
  runId: Number$1,
52304
51512
  state: Literals([
52305
51513
  "idle",
@@ -52329,8 +51537,22 @@ const TerminalPayload = Struct({
52329
51537
  args: optional(ArraySchema(String$1)),
52330
51538
  command: optional(String$1),
52331
51539
  cwd: String$1,
51540
+ env: optional(Record(String$1, String$1)),
52332
51541
  sessionId: optional(String$1)
52333
51542
  });
51543
+ const RunScript = Struct({
51544
+ baseOrigin: optional(String$1),
51545
+ command: String$1,
51546
+ cwd: String$1,
51547
+ env: optional(Record(String$1, String$1)),
51548
+ name: String$1,
51549
+ origin: optional(String$1),
51550
+ packageFolder: String$1,
51551
+ packagePath: String$1,
51552
+ portless: optional(Boolean$1),
51553
+ service: optional(String$1),
51554
+ sessionId: String$1
51555
+ });
52334
51556
  const AgentSession = Struct({
52335
51557
  args: ArraySchema(String$1),
52336
51558
  command: String$1,
@@ -52505,14 +51727,10 @@ var RpcContracts = class extends make$15(make$18("agents.create", {
52505
51727
  cwd: String$1,
52506
51728
  force: Boolean$1
52507
51729
  })
52508
- }), make$18("runs.scripts", {
51730
+ }), make$18("runs.portless", {
52509
51731
  error: TerminalError,
52510
51732
  payload: Struct({ cwd: String$1 }),
52511
- success: ArraySchema(Struct({
52512
- command: String$1,
52513
- name: String$1,
52514
- tasks: ArraySchema(String$1)
52515
- }))
51733
+ success: ArraySchema(RunScript)
52516
51734
  }), make$18("terminal.write", {
52517
51735
  error: TerminalError,
52518
51736
  payload: Struct({
@@ -52520,6 +51738,7 @@ var RpcContracts = class extends make$15(make$18("agents.create", {
52520
51738
  command: optional(String$1),
52521
51739
  cwd: String$1,
52522
51740
  data: String$1,
51741
+ env: optional(Record(String$1, String$1)),
52523
51742
  sessionId: optional(String$1)
52524
51743
  }),
52525
51744
  success: TerminalState
@@ -52530,6 +51749,7 @@ var RpcContracts = class extends make$15(make$18("agents.create", {
52530
51749
  cols: Number$1,
52531
51750
  command: optional(String$1),
52532
51751
  cwd: String$1,
51752
+ env: optional(Record(String$1, String$1)),
52533
51753
  rows: Number$1,
52534
51754
  sessionId: optional(String$1)
52535
51755
  }),
@@ -52542,11 +51762,6 @@ var RpcContracts = class extends make$15(make$18("agents.create", {
52542
51762
  error: TerminalError,
52543
51763
  payload: TerminalPayload,
52544
51764
  success: TerminalState
52545
- }), make$18("terminal.ports", {
52546
- error: TerminalError,
52547
- payload: TerminalPayload,
52548
- stream: true,
52549
- success: ArraySchema(Number$1)
52550
51765
  }), make$18("terminal.watch", {
52551
51766
  error: TerminalError,
52552
51767
  payload: TerminalPayload,
@@ -52706,7 +51921,7 @@ var GitWorkspace = class extends Service()("@deslop/git/service/GitWorkspace", {
52706
51921
  "--format=%(refname:short)",
52707
51922
  "refs/remotes"
52708
51923
  ]), map$4((lines) => pipe(lines, filter$2((name) => !endsWith("/HEAD")(name)), map$7((name) => new GitBranch({
52709
- name: pipe(split$1("/")(name), drop$1(1), join$3("/")),
51924
+ name: pipe(split$1("/")(name), drop$1(1), join$2("/")),
52710
51925
  remote: split$1("/")(name)[0],
52711
51926
  type: "remote"
52712
51927
  })), filter$2((branch) => isNonEmpty$1(branch.name)), appendAll(localBranches)))))),
@@ -52890,7 +52105,7 @@ var GitWorktree = class extends Service()("@deslop/git/service/GitWorktree", { m
52890
52105
  "--exclude-standard"
52891
52106
  ]), flatMap$2((files) => forEach$1(files, (filePath) => pipe(fs.readFileString(path.join(config.cwd, filePath)), orElseSucceed(() => ""), map$4((content) => new GitDiff({
52892
52107
  filePath,
52893
- patch: `diff --git a/${filePath} b/${filePath}\nnew file mode 100644\n--- /dev/null\n+++ b/${filePath}\n@@ -0,0 +1,${length(split$1("\n")(content))} @@\n${pipe(split$1("\n")(content), map$7((line) => `+${line}`), join$3("\n"))}`,
52108
+ patch: `diff --git a/${filePath} b/${filePath}\nnew file mode 100644\n--- /dev/null\n+++ b/${filePath}\n@@ -0,0 +1,${length(split$1("\n")(content))} @@\n${pipe(split$1("\n")(content), map$7((line) => `+${line}`), join$2("\n"))}`,
52894
52109
  segments: [new GitDiffSegment({
52895
52110
  filePath,
52896
52111
  fingerprint: content,
@@ -53233,49 +52448,255 @@ var GitWorktree = class extends Service()("@deslop/git/service/GitWorktree", { m
53233
52448
  static layer = flow(this.make, effect(this));
53234
52449
  };
53235
52450
  //#endregion
53236
- //#region ../../packages/terminal/src/service.ts
53237
- function parseProcessParents(output) {
53238
- return new Map(pipe(linesIterator(output), fromIterable$2, filterMap$1((line) => {
53239
- const columns = split$1(/\s+/)(trim(line));
53240
- const pid = Number(columns[0]);
53241
- const ppid = Number(columns[1]);
53242
- return Number.isFinite(pid) && Number.isFinite(ppid) ? succeed$7(make$63(pid, ppid)) : failVoid;
53243
- })));
52451
+ //#region ../../packages/portless/src/lib/utils.ts
52452
+ function command(script, port) {
52453
+ return make$40("vp", [
52454
+ "run",
52455
+ script.name,
52456
+ .../^vp\s+dev(?:\s|$)/u.test(script.command) ? [
52457
+ "--host",
52458
+ "127.0.0.1",
52459
+ "--port",
52460
+ port.toString(),
52461
+ "--strictPort"
52462
+ ] : []
52463
+ ]);
53244
52464
  }
53245
- function parseListeningPorts(output) {
53246
- return pipe(linesIterator(output), fromIterable$2, filterMap$1((line) => {
53247
- const columns = split$1(/\s+/)(trim(line));
53248
- const port = Number(columns[3]?.match(/:(\d+)$/)?.[1]);
53249
- const pid = Number(line.match(/pid=(\d+)/)?.[1]);
53250
- return Number.isFinite(port) && Number.isFinite(pid) ? succeed$7({
53251
- pid,
53252
- port
53253
- }) : failVoid;
52465
+ const discover = fnUntraced(function* (cwd, input) {
52466
+ const execString = yield* ChildProcessSpawner.useSync((spawner) => spawner.string);
52467
+ const fs = yield* FileSystem;
52468
+ const path = yield* Path$1;
52469
+ const output = yield* execString(make$40("git", [
52470
+ "ls-files",
52471
+ "-co",
52472
+ "--exclude-standard",
52473
+ "--",
52474
+ "package.json",
52475
+ "**/package.json"
52476
+ ], { cwd }));
52477
+ return yield* pipe(pipe(split$1("\n")(output), filter$2((path) => path === "package.json" || endsWith("/package.json")(path))), map$7((packagePath) => pipe(pipe(fs.readFileString(path.join(cwd, packagePath)), map$4((source) => ({
52478
+ packageJson: JSON.parse(source),
52479
+ packagePath
52480
+ })), catch_$2(() => succeed$3(void 0))), flatMap$2((result) => {
52481
+ if (result === void 0) return succeed$3([]);
52482
+ const packageDirectory = result.packagePath === "package.json" ? cwd : path.join(cwd, path.dirname(result.packagePath));
52483
+ const folder = path.basename(packageDirectory);
52484
+ const scriptEntries = pipe(Object.entries(result.packageJson.scripts ?? {}), filter$2((entry) => entry[0] === "dev" || startsWith("dev:")(entry[0])));
52485
+ const packageOrigin = `http://${[
52486
+ folder,
52487
+ path.basename(cwd),
52488
+ "localhost"
52489
+ ].join(".")}:${input.proxyPort}`;
52490
+ return pipe(scriptEntries, map$7((entry) => {
52491
+ const name = entry[0];
52492
+ const scriptCommand = entry[1];
52493
+ return map$4(input.port(`${result.packagePath}:${name}`), (port) => {
52494
+ const service = /^dev:(.+)$/u.exec(name)?.[1] ?? "dev";
52495
+ const host = [
52496
+ service,
52497
+ folder,
52498
+ path.basename(cwd),
52499
+ "localhost"
52500
+ ].join(".");
52501
+ const origin = `http://${host}:${input.proxyPort}`;
52502
+ return {
52503
+ host,
52504
+ port,
52505
+ script: {
52506
+ baseOrigin: packageOrigin,
52507
+ command: scriptCommand,
52508
+ cwd: packageDirectory,
52509
+ env: {
52510
+ HOST: "127.0.0.1",
52511
+ PORT: port.toString(),
52512
+ PORTLESS_BASE_ORIGIN: packageOrigin,
52513
+ PORTLESS_ORIGIN: origin,
52514
+ VITE_PORTLESS_BASE_ORIGIN: packageOrigin,
52515
+ VITE_PORTLESS_ORIGIN: origin
52516
+ },
52517
+ name,
52518
+ origin,
52519
+ packageFolder: folder,
52520
+ packagePath: result.packagePath,
52521
+ service,
52522
+ sessionId: `${result.packagePath}:${name}:${Date.now()}:${Math.random()}`
52523
+ }
52524
+ };
52525
+ });
52526
+ }), all);
52527
+ }))), all, map$4((routes) => flatten$3(routes).sort((left, right) => `${left.script.packagePath}:${left.script.name}`.localeCompare(`${right.script.packagePath}:${right.script.name}`))));
52528
+ });
52529
+ //#endregion
52530
+ //#region ../../packages/portless/src/http.ts
52531
+ const INJECTED_HEAD = `<script>
52532
+ (() => {
52533
+ if (window.__deslopBrowserBridge) return
52534
+ window.__deslopBrowserBridge = true
52535
+
52536
+ const serialize = value => {
52537
+ if (typeof value === 'string') return value
52538
+ try { return JSON.stringify(value) } catch { return String(value) }
52539
+ }
52540
+ const send = (level, message) => window.parent?.postMessage({__deslopBrowserLog: true, level, message}, '*')
52541
+ const sendFavicon = () => {
52542
+ const icon = Array.from(document.head.querySelectorAll('link')).find(link => link.rel === 'shortcut icon' || link.rel.split(/\\s+/).includes('icon'))
52543
+ window.parent?.postMessage({__deslopBrowserFavicon: true, href: icon?.href}, '*')
52544
+ }
52545
+
52546
+ for (const level of ['debug', 'info', 'log', 'warn', 'error']) {
52547
+ const original = console[level]
52548
+ console[level] = (...args) => {
52549
+ send(level, args.map(serialize).join(' '))
52550
+ original.apply(console, args)
52551
+ }
52552
+ }
52553
+
52554
+ window.addEventListener('error', event => send('error', event.message || 'Resource failed to load'), true)
52555
+ window.addEventListener('unhandledrejection', event => send('error', serialize(event.reason)))
52556
+ window.addEventListener('message', event => {
52557
+ if (event.data?.__deslopBrowserClear !== true) return
52558
+ localStorage.clear()
52559
+ sessionStorage.clear()
52560
+ document.cookie.split(';').forEach(cookie => {
52561
+ document.cookie = cookie.replace(/^\\s*([^=]+)=.*$/, '$1=; Max-Age=0; Path=/')
52562
+ })
52563
+ caches?.keys?.().then(keys => Promise.all(keys.map(key => caches.delete(key))))
52564
+ navigator.serviceWorker?.getRegistrations?.().then(registrations => Promise.all(registrations.map(registration => registration.unregister())))
52565
+ location.reload()
52566
+ })
52567
+
52568
+ const sendLocation = () => window.parent?.postMessage({__deslopBrowserLocation: true, path: location.pathname + location.search + location.hash}, '*')
52569
+ const wrapHistory = name => {
52570
+ const original = history[name]
52571
+ history[name] = function(...args) {
52572
+ const result = original.apply(this, args)
52573
+ sendLocation()
52574
+ return result
52575
+ }
52576
+ }
52577
+ wrapHistory('pushState')
52578
+ wrapHistory('replaceState')
52579
+ window.addEventListener('popstate', sendLocation)
52580
+ window.addEventListener('hashchange', sendLocation)
52581
+
52582
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', sendFavicon, {once: true})
52583
+ else sendFavicon()
52584
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', sendLocation, {once: true})
52585
+ else sendLocation()
52586
+ })()
52587
+ <\/script>
52588
+ <script crossorigin="anonymous" src="//unpkg.com/react-scan/dist/auto.global.js" onload="window.reactScan?.({allowInIframe: true, _debug: 'verbose'})"><\/script>
52589
+ <script src="https://unpkg.com/react-grab/dist/index.global.js"><\/script>`;
52590
+ const injectScripts = fnUntraced(function* (html) {
52591
+ return /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (match) => `${match}\n${INJECTED_HEAD}`) : `${INJECTED_HEAD}\n${html}`;
52592
+ });
52593
+ const proxy = fnUntraced(function* (request, origin) {
52594
+ const webRequest = yield* toWeb(request);
52595
+ const [pathname = "/", search = ""] = request.url.split("?");
52596
+ const upstreamHeaders = new Headers(webRequest.headers);
52597
+ upstreamHeaders.set("host", new URL(origin).host);
52598
+ const upstreamRequest = new Request(`${origin}${pathname}${search ? `?${search}` : ""}`, {
52599
+ body: webRequest.body,
52600
+ headers: upstreamHeaders,
52601
+ method: webRequest.method,
52602
+ redirect: webRequest.redirect,
52603
+ signal: webRequest.signal
52604
+ });
52605
+ const upstreamResponse = yield* tryPromise(() => fetch(upstreamRequest));
52606
+ const headers = new Headers(upstreamResponse.headers);
52607
+ headers.delete("content-length");
52608
+ headers.delete("content-encoding");
52609
+ if (!(request.method === "GET" && (upstreamResponse.headers.get("content-type") ?? "").includes("text/html"))) return fromWeb(new Response(upstreamResponse.body, {
52610
+ headers,
52611
+ status: upstreamResponse.status,
52612
+ statusText: upstreamResponse.statusText
53254
52613
  }));
53255
- }
53256
- function isDescendant(pid, ancestorPid, parents) {
53257
- let current = pid;
53258
- const seen = /* @__PURE__ */ new Set();
53259
- while (!seen.has(current)) {
53260
- if (current === ancestorPid) return true;
53261
- seen.add(current);
53262
- const parent = parents.get(current);
53263
- if (!parent || parent === current) return false;
53264
- current = parent;
53265
- }
53266
- return false;
53267
- }
53268
- function descendantsOf(ancestorPid, parents) {
53269
- return pipe(fromIterable$2(parents.keys()), filter$2((pid) => pid !== ancestorPid && isDescendant(pid, ancestorPid, parents)));
53270
- }
53271
- const commandString = fnUntraced(function* (command, args, message) {
53272
- return yield* pipe((yield* ChildProcessSpawner.useSync((spawner) => spawner.string))(make$40(command, args)), mapError$2((cause) => new TerminalError({
53273
- cause,
53274
- message
53275
- })));
52614
+ const body = yield* tryPromise(() => upstreamResponse.text());
52615
+ headers.set("content-type", "text/html; charset=utf-8");
52616
+ return fromWeb(new Response(yield* injectScripts(body), {
52617
+ headers,
52618
+ status: upstreamResponse.status,
52619
+ statusText: upstreamResponse.statusText
52620
+ }));
52621
+ });
52622
+ const proxyWebSocket = fnUntraced(function* (request, origin) {
52623
+ const [pathname = "/", search = ""] = request.url.split("?");
52624
+ const protocols = request.headers["sec-websocket-protocol"]?.split(",").map((protocol) => protocol.trim()).filter((protocol) => protocol.length > 0);
52625
+ const inbound = yield* request.upgrade;
52626
+ const upstreamUrl = new URL(origin);
52627
+ upstreamUrl.protocol = upstreamUrl.protocol === "https:" ? "wss:" : "ws:";
52628
+ upstreamUrl.pathname = pathname;
52629
+ upstreamUrl.search = search;
52630
+ const outbound = yield* makeWebSocket(upstreamUrl.toString(), { protocols }).pipe(provide(layerWebSocketConstructorGlobal));
52631
+ const writeInbound = yield* inbound.writer;
52632
+ const writeOutbound = yield* outbound.writer;
52633
+ yield* outbound.runRaw((message) => writeInbound(message)).pipe(catchReason("SocketError", "SocketCloseError", (reason) => writeInbound(new CloseEvent(reason.code, reason.closeReason)).pipe(catch_$2(() => void_$1))), catch_$2(() => writeInbound(new CloseEvent(1011, "proxy error")).pipe(catch_$2(() => void_$1))), forkScoped);
52634
+ yield* inbound.runRaw((message) => writeOutbound(typeof message === "string" ? message : message.slice())).pipe(catch_$2(() => void_$1), ensuring$2(writeOutbound(new CloseEvent()).pipe(catch_$2(() => void_$1))));
52635
+ return empty();
53276
52636
  });
53277
- const readProcessParents = pipe(commandString("ps", ["-eo", "pid=,ppid="], "failed to list terminal processes"), map$4(parseProcessParents));
53278
- const readListeningPorts = pipe(commandString("ss", ["-H", "-ltnp"], "failed to list terminal ports"), map$4(parseListeningPorts));
52637
+ const requestHostname = fnUntraced(function* (host) {
52638
+ return fromUndefinedOr(host?.split(":")[0]);
52639
+ });
52640
+ function isLocalHostname(hostname) {
52641
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]";
52642
+ }
52643
+ var Portless = class Portless extends Service()("@deslop/portless/Portless", { make: sync(() => {
52644
+ const ports = /* @__PURE__ */ new Map();
52645
+ const routes = /* @__PURE__ */ new Map();
52646
+ const middleware = fnUntraced(function* (app) {
52647
+ const request = yield* HttpServerRequest;
52648
+ const hostname = yield* requestHostname(request.headers["host"]);
52649
+ if (isNone(hostname) || isLocalHostname(hostname.value)) return yield* app;
52650
+ if (!hostname.value.endsWith(".localhost")) return yield* app;
52651
+ const route = yield* lookup(request.headers["host"]);
52652
+ if (isNone(route)) return empty({ status: 404 });
52653
+ if (request.headers["upgrade"]?.toLowerCase() === "websocket") return yield* proxyWebSocket(request, route.value);
52654
+ return yield* proxy(request, route.value);
52655
+ });
52656
+ const lookup = fnUntraced(function* (host) {
52657
+ return pipe(yield* requestHostname(host), flatMap$6((hostname) => fromUndefinedOr(routes.get(hostname))));
52658
+ });
52659
+ const port = fnUntraced(function* (key) {
52660
+ const existing = ports.get(key);
52661
+ if (existing !== void 0) return existing;
52662
+ const reserved = new Set(ports.values());
52663
+ for (let port = 4e3; port <= 4999; port += 1) {
52664
+ const occupied = yield* pipe(tryPromise(() => fetch(`http://127.0.0.1:${port}`, { signal: AbortSignal.timeout(100) })), as(true), catch_$2(() => succeed$3(false)));
52665
+ if (!reserved.has(port) && !occupied) {
52666
+ ports.set(key, port);
52667
+ return port;
52668
+ }
52669
+ }
52670
+ throw new Error("no portless app ports available");
52671
+ });
52672
+ return {
52673
+ middleware,
52674
+ port,
52675
+ register: fnUntraced(function* (host, port) {
52676
+ routes.set(host, `http://127.0.0.1:${port}`);
52677
+ }),
52678
+ scripts: fnUntraced(function* (cwd, input) {
52679
+ return yield* pipe(discover(cwd, {
52680
+ port: (sessionId) => port(`${cwd}:${sessionId}`),
52681
+ proxyPort: input.proxyPort
52682
+ }), map$4((routes) => routes.map((route) => ({
52683
+ host: route.host,
52684
+ port: route.port,
52685
+ script: {
52686
+ ...route.script,
52687
+ preparedCommand: command(route.script, route.port)
52688
+ }
52689
+ }))));
52690
+ })
52691
+ };
52692
+ }) }) {
52693
+ static layer = effect(this, this.make);
52694
+ static middleware = fnUntraced(function* (app) {
52695
+ return yield* (yield* Portless).middleware(app);
52696
+ });
52697
+ };
52698
+ //#endregion
52699
+ //#region ../../packages/terminal/src/service.ts
53279
52700
  function snapshotEvents(data) {
53280
52701
  if (data === "") return empty$13();
53281
52702
  const events = [];
@@ -53285,9 +52706,6 @@ function snapshotEvents(data) {
53285
52706
  });
53286
52707
  return events;
53287
52708
  }
53288
- function samePorts(left, right) {
53289
- return left.length === right.length && every(left, (leftPort, index) => leftPort === right[index]);
53290
- }
53291
52709
  function parseTitleSignal(title) {
53292
52710
  const trimmed = trim(title);
53293
52711
  if (/^\[\s*[!.]\s*\]\s*Action Required\b/i.test(trimmed)) return {
@@ -53349,18 +52767,16 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53349
52767
  const screenLock = yield* make$47(1);
53350
52768
  const sequenceRef = yield* make$38(0);
53351
52769
  const signalBuffer = yield* make$38("");
53352
- const portOwners = yield* make$38(/* @__PURE__ */ new Map());
53353
52770
  const processRef = yield* make$38(void 0);
53354
52771
  const sizeRef = yield* make$38({
53355
52772
  cols: 120,
53356
52773
  rows: 32
53357
52774
  });
53358
52775
  const shell = yield* string("SHELL").pipe(orElseSucceed(() => "bash"));
53359
- const processCommand = config.command ?? shell;
53360
- const processArgs = config.args ?? [];
53361
- const autostart = config.command === void 0;
52776
+ const processCommand = config.preparedCommand?.command ?? config.command ?? shell;
52777
+ const processArgs = config.preparedCommand?.args ?? config.args ?? [];
52778
+ const autostart = config.command === void 0 && config.preparedCommand === void 0;
53362
52779
  const stateRef = yield* make$3({
53363
- ports: [],
53364
52780
  runId: 0,
53365
52781
  state: autostart ? "starting" : "idle",
53366
52782
  title: ""
@@ -53411,17 +52827,10 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53411
52827
  }
53412
52828
  const startRun = pipe(update(stateRef, (state) => ({
53413
52829
  ...state,
53414
- ports: [],
53415
52830
  runId: state.runId + 1,
53416
52831
  state: "starting",
53417
52832
  title: ""
53418
52833
  })), andThen(get(stateRef)));
53419
- function setPorts(ports) {
53420
- return updateSome(stateRef, (state) => samePorts(state.ports, ports) ? none() : some$1({
53421
- ...state,
53422
- ports: [...ports]
53423
- }));
53424
- }
53425
52834
  function readSignals(data) {
53426
52835
  for (const match of data.matchAll(/\x1b\](?:0|2);([^\x07\x1b]*)(?:\x07|\x1b\\)/gu)) {
53427
52836
  const title = match[1];
@@ -53434,24 +52843,17 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53434
52843
  yield* set$4(signalBuffer, next.pending);
53435
52844
  readSignals(next.complete);
53436
52845
  });
53437
- const interruptProcessTree = fnUntraced(function* (subprocess, signal) {
53438
- const descendants = yield* pipe(all([readProcessParents, get$3(portOwners)]), map$4(([parents, owners]) => dedupe([...descendantsOf(subprocess.pid, parents), ...fromIterable$2(owners.values())])), timeoutOption("250 millis"), map$4((option) => getOrElse$1(option, empty$13)), catch_$2(() => succeed$3(empty$13())));
52846
+ const interruptProcess = fnUntraced(function* (subprocess, signal) {
53439
52847
  yield* sync(() => {
53440
- try {
53441
- if (nodeProcess.platform !== "win32") nodeProcess.kill(-subprocess.pid, signal);
53442
- } catch {}
53443
- for (const pid of descendants.toReversed()) try {
53444
- nodeProcess.kill(pid, signal);
53445
- } catch {}
53446
52848
  try {
53447
52849
  subprocess.kill(signal);
53448
52850
  } catch {}
53449
52851
  });
53450
52852
  });
53451
52853
  const terminateProcess = fnUntraced(function* (subprocess) {
53452
- yield* interruptProcessTree(subprocess, "SIGTERM");
52854
+ yield* interruptProcess(subprocess, "SIGTERM");
53453
52855
  yield* sleep("250 millis");
53454
- yield* interruptProcessTree(subprocess, "SIGKILL");
52856
+ yield* interruptProcess(subprocess, "SIGKILL");
53455
52857
  });
53456
52858
  const writeScreen = fnUntraced(function* (data) {
53457
52859
  yield* withPermit(screenLock, pipe(callback$1((resume) => {
@@ -53465,8 +52867,6 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53465
52867
  });
53466
52868
  const clearProcess = fnUntraced(function* (handle) {
53467
52869
  yield* update$1(processRef, (current) => current === handle ? void 0 : current);
53468
- yield* set$4(portOwners, /* @__PURE__ */ new Map());
53469
- yield* setPorts([]);
53470
52870
  });
53471
52871
  const stopProcess = fnUntraced(function* (state) {
53472
52872
  const handle = yield* get$3(processRef);
@@ -53498,6 +52898,7 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53498
52898
  cwd: config.cwd,
53499
52899
  env: {
53500
52900
  ...process.env,
52901
+ ...config.env,
53501
52902
  TERM: "xterm-256color"
53502
52903
  },
53503
52904
  name: "xterm-256color",
@@ -53540,22 +52941,6 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53540
52941
  discard: true
53541
52942
  }));
53542
52943
  if (autostart) yield* pipe(startProcess(), withPermit(lifecycleLock), catch_$2(() => setState("failed")));
53543
- yield* pipe(gen(function* () {
53544
- const process = yield* get$3(processRef);
53545
- if (!process?.process.pid) {
53546
- yield* set$4(portOwners, /* @__PURE__ */ new Map());
53547
- yield* setPorts([]);
53548
- return;
53549
- }
53550
- const [parents, listeningPorts] = yield* all([readProcessParents, readListeningPorts]);
53551
- const nextPortOwners = /* @__PURE__ */ new Map();
53552
- const nextPorts = pipe(listeningPorts, filter$2((port) => isDescendant(port.pid, process.process.pid, parents)), map$7((port) => {
53553
- nextPortOwners.set(port.port, port.pid);
53554
- return port.port;
53555
- }), dedupe, sort(Number$5));
53556
- yield* set$4(portOwners, nextPortOwners);
53557
- yield* setPorts(nextPorts);
53558
- }), ignore$1, repeat(spaced("1 second")), forkScoped);
53559
52944
  const resize = fnUntraced(function* (nextSize) {
53560
52945
  const size = yield* get$3(sizeRef);
53561
52946
  if (size.cols === nextSize.cols && size.rows === nextSize.rows) return;
@@ -53604,7 +52989,6 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53604
52989
  ...filter$2(pending, (event) => event.sequence > snapshot.sequence)
53605
52990
  ]), concat(fromEffectRepeat(take$2(subscription))));
53606
52991
  })));
53607
- const ports = pipe(changes(stateRef), map$2((state) => state.ports), changesWith(samePorts));
53608
52992
  const updates = merge$1(changes(stateRef).pipe(map$2((state) => ({
53609
52993
  state,
53610
52994
  type: "state"
@@ -53613,7 +52997,6 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53613
52997
  type: "event"
53614
52998
  }))));
53615
52999
  return {
53616
- ports,
53617
53000
  resize: fnUntraced(function* (size) {
53618
53001
  return yield* pipe(resize(size), andThen(get(stateRef)));
53619
53002
  }),
@@ -53633,70 +53016,12 @@ var Terminal = class extends Service()("@deslop/terminal/service/Terminal", { ma
53633
53016
  static layer = flow(this.make, effect(this));
53634
53017
  };
53635
53018
  //#endregion
53636
- //#region ../../packages/terminal/src/utils.ts
53637
- function splitParallelCommands(script) {
53638
- const state = pipe(split$1("")(script), reduce({
53639
- commands: [],
53640
- current: "",
53641
- escaped: false,
53642
- skipNext: false
53643
- }, (state, char, index) => {
53644
- if (state.skipNext) return {
53645
- ...state,
53646
- skipNext: false
53647
- };
53648
- if (state.escaped) return {
53649
- ...state,
53650
- current: state.current + char,
53651
- escaped: false
53652
- };
53653
- if (char === "\\") return {
53654
- ...state,
53655
- current: state.current + char,
53656
- escaped: true
53657
- };
53658
- if (state.quote) return {
53659
- ...state,
53660
- current: state.current + char,
53661
- quote: char === state.quote ? void 0 : state.quote
53662
- };
53663
- if (char === "\"" || char === "'") return {
53664
- ...state,
53665
- current: state.current + char,
53666
- quote: char
53667
- };
53668
- if (char === "&" && script[index + 1] === "&") return {
53669
- ...state,
53670
- current: `${state.current}&&`,
53671
- skipNext: true
53672
- };
53673
- if (char !== "&") return {
53674
- ...state,
53675
- current: state.current + char
53676
- };
53677
- return pipe(liftPredicate(trim(state.current), isNonEmpty$1), match$5({
53678
- onNone: () => ({
53679
- ...state,
53680
- current: ""
53681
- }),
53682
- onSome: (command) => ({
53683
- ...state,
53684
- commands: [...state.commands, command],
53685
- current: ""
53686
- })
53687
- }));
53688
- }));
53689
- return pipe(liftPredicate(trim(state.current), isNonEmpty$1), match$5({
53690
- onNone: () => state.commands,
53691
- onSome: (command) => [...state.commands, command]
53692
- }));
53693
- }
53694
- //#endregion
53695
53019
  //#region src/rpcs/handlers.ts
53696
53020
  const TerminalSessionKey = Struct({
53697
53021
  args: optional(ArraySchema(String$1)),
53698
53022
  command: optional(String$1),
53699
53023
  cwd: String$1,
53024
+ env: optional(Record(String$1, String$1)),
53700
53025
  sessionId: optional(String$1)
53701
53026
  });
53702
53027
  const emptyReviewState = new ReviewState({
@@ -53724,7 +53049,45 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
53724
53049
  const terminals = yield* TerminalSessions;
53725
53050
  const gitWorktrees = yield* GitWorktreeSessions;
53726
53051
  const fs = yield* FileSystem;
53052
+ const portless = yield* Portless;
53053
+ const portlessScripts = yield* make$38(empty$6());
53727
53054
  const reviewStore = toSchemaStore(yield* KeyValueStore, ReviewState);
53055
+ const portlessWorktrees = yield* make$46({
53056
+ idleTimeToLive: infinity,
53057
+ lookup: fnUntraced(function* (cwd) {
53058
+ const scripts = yield* pipe(portless.scripts(cwd, { proxyPort: process.env["PORT"] ?? "4010" }), mapError$2((cause) => new TerminalError({
53059
+ cause,
53060
+ message: `failed to discover portless scripts in ${cwd}`
53061
+ })));
53062
+ yield* all(pipe(scripts, map$7((script) => all([portless.register(script.host, script.port), update$1(portlessScripts, (current) => set$2(current, script.script.sessionId, script.script))], { discard: true }))), { discard: true });
53063
+ return pipe(scripts, map$7((route) => ({
53064
+ baseOrigin: route.script.baseOrigin,
53065
+ command: route.script.command,
53066
+ cwd: route.script.cwd,
53067
+ name: route.script.name,
53068
+ origin: route.script.origin,
53069
+ packageFolder: route.script.packageFolder,
53070
+ packagePath: route.script.packagePath,
53071
+ portless: true,
53072
+ service: route.script.service,
53073
+ sessionId: route.script.sessionId
53074
+ })));
53075
+ })
53076
+ });
53077
+ const terminalSession = fnUntraced(function* (input) {
53078
+ if (input.sessionId === void 0 || input.command !== void 0) return input;
53079
+ const script = pipe(yield* get$3(portlessScripts), get$1(input.sessionId), getOrUndefined$1);
53080
+ if (script === void 0) return input;
53081
+ return {
53082
+ cwd: script.cwd,
53083
+ env: script.env,
53084
+ preparedCommand: script.preparedCommand,
53085
+ sessionId: script.sessionId
53086
+ };
53087
+ });
53088
+ const terminal = fnUntraced(function* (input) {
53089
+ return yield* pipe(terminalSession(input), flatMap$2((session) => get$6(terminals, session)));
53090
+ });
53728
53091
  const reviewStateKey = fnUntraced(function* (input) {
53729
53092
  const root = yield* pipe(fs.realPath(input.cwd), orElseSucceed(() => input.cwd));
53730
53093
  return Buffer.from(`${root}\u0000${input.base}`, "utf8").toString("base64url");
@@ -53791,7 +53154,7 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
53791
53154
  "projects.branches": (payload) => git.branches(payload.cwd),
53792
53155
  "projects.createWorktree": (payload) => git.createWorktree(payload),
53793
53156
  "projects.deleteWorktree": (payload) => git.deleteWorktree(payload),
53794
- "projects.watch": () => unwrap$1(pipe(get(git.projects), map$4((projects) => pipe(make$43(projects), concat(drop(1)(changes(git.projects))))))),
53157
+ "projects.watch": () => unwrap$1(map$4(get(git.projects), (projects) => pipe(make$43(projects), concat(drop(1)(changes(git.projects)))))),
53795
53158
  "review.comments.resolve": (payload) => updateReviewState(payload, (state) => {
53796
53159
  const key = commentKey(payload);
53797
53160
  return new ReviewState({
@@ -53839,26 +53202,15 @@ const RpcHandlers = RpcContracts.toLayer(gen(function* () {
53839
53202
  from: payload.from,
53840
53203
  to: payload.to
53841
53204
  })))),
53842
- "runs.scripts": (payload) => pipe(tryPromise({
53843
- catch: (cause) => new TerminalError({
53844
- cause,
53845
- message: `failed to read package.json in ${payload.cwd}`
53846
- }),
53847
- try: () => readFile(join(payload.cwd, "package.json"), "utf8")
53848
- }), map$4(decodeUnknownSync(fromJsonString(Struct({ scripts: optional(Record(String$1, String$1)) })))), map$4((packageJson) => pipe(packageJson.scripts ?? {}, toEntries, map$7(([name, command]) => ({
53849
- command,
53850
- name,
53851
- tasks: splitParallelCommands(command)
53852
- }))))),
53853
- "terminal.ports": (payload) => unwrap$1(pipe(get$6(terminals, TerminalSessionKey.make(payload)), map$4((terminal) => terminal.ports))),
53854
- "terminal.resize": (payload) => pipe(get$6(terminals, TerminalSessionKey.make(payload)), flatMap$2((terminal) => terminal.resize({
53205
+ "runs.portless": (payload) => get$6(portlessWorktrees, payload.cwd),
53206
+ "terminal.resize": (payload) => pipe(terminal(TerminalSessionKey.make(payload)), flatMap$2((terminal) => terminal.resize({
53855
53207
  cols: payload.cols,
53856
53208
  rows: payload.rows
53857
53209
  }))),
53858
- "terminal.restart": (payload) => pipe(get$6(terminals, TerminalSessionKey.make(payload)), flatMap$2((terminal) => terminal.restart())),
53859
- "terminal.stop": (payload) => pipe(get$6(terminals, TerminalSessionKey.make(payload)), flatMap$2((terminal) => terminal.stop())),
53860
- "terminal.watch": (payload) => unwrap$1(pipe(get$6(terminals, TerminalSessionKey.make(payload)), map$4((terminal) => terminal.updates))),
53861
- "terminal.write": (payload) => pipe(get$6(terminals, TerminalSessionKey.make(payload)), flatMap$2((terminal) => terminal.write(payload.data)))
53210
+ "terminal.restart": (payload) => flatMap$2(terminal(TerminalSessionKey.make(payload)), (terminal) => terminal.restart()),
53211
+ "terminal.stop": (payload) => flatMap$2(terminal(TerminalSessionKey.make(payload)), (terminal) => terminal.stop()),
53212
+ "terminal.watch": (payload) => unwrap$1(map$4(terminal(TerminalSessionKey.make(payload)), (terminal) => terminal.updates)),
53213
+ "terminal.write": (payload) => pipe(terminal(TerminalSessionKey.make(payload)), flatMap$2((terminal) => terminal.write(payload.data)))
53862
53214
  });
53863
53215
  }));
53864
53216
  //#endregion
@@ -70641,104 +69993,7 @@ function OtelLayer(serviceName) {
70641
69993
  }
70642
69994
  //#endregion
70643
69995
  //#region src/lib/serverRuntime.ts
70644
- const LiveLayers = pipe(empty$11, provideMerge(RpcHandlers), provideMerge(GitWorkspace.layer), provideMerge(unwrap$4(pipe(string("HOME"), withDefault(process.cwd()), map$4((home) => layerFileSystem(path.join(home, ".deslop")))))), provideMerge(OtelLayer("workbench-server")), provideMerge(layer$16), provideMerge(layerMsgPack));
70645
- //#endregion
70646
- //#region ../../packages/browser/src/http.ts
70647
- const INJECTED_HEAD = `<script>
70648
- (() => {
70649
- if (window.__deslopBrowserBridge) return
70650
- window.__deslopBrowserBridge = true
70651
-
70652
- const serialize = value => {
70653
- if (typeof value === 'string') return value
70654
- try { return JSON.stringify(value) } catch { return String(value) }
70655
- }
70656
- const send = (level, message) => window.parent?.postMessage({__deslopBrowserLog: true, level, message}, '*')
70657
- const sendFavicon = () => {
70658
- const icon = Array.from(document.head.querySelectorAll('link')).find(link => link.rel === 'shortcut icon' || link.rel.split(/\\s+/).includes('icon'))
70659
- window.parent?.postMessage({__deslopBrowserFavicon: true, href: icon?.href}, '*')
70660
- }
70661
-
70662
- for (const level of ['debug', 'info', 'log', 'warn', 'error']) {
70663
- const original = console[level]
70664
- console[level] = (...args) => {
70665
- send(level, args.map(serialize).join(' '))
70666
- original.apply(console, args)
70667
- }
70668
- }
70669
-
70670
- window.addEventListener('error', event => send('error', event.message || 'Resource failed to load'), true)
70671
- window.addEventListener('unhandledrejection', event => send('error', serialize(event.reason)))
70672
- window.addEventListener('message', event => {
70673
- if (event.data?.__deslopBrowserClear !== true) return
70674
- localStorage.clear()
70675
- sessionStorage.clear()
70676
- document.cookie.split(';').forEach(cookie => {
70677
- document.cookie = cookie.replace(/^\\s*([^=]+)=.*$/, '$1=; Max-Age=0; Path=/')
70678
- })
70679
- caches?.keys?.().then(keys => Promise.all(keys.map(key => caches.delete(key))))
70680
- navigator.serviceWorker?.getRegistrations?.().then(registrations => Promise.all(registrations.map(registration => registration.unregister())))
70681
- location.reload()
70682
- })
70683
-
70684
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', sendFavicon, {once: true})
70685
- else sendFavicon()
70686
- })()
70687
- <\/script>
70688
- <script crossorigin="anonymous" src="//unpkg.com/react-scan/dist/auto.global.js" onload="window.reactScan?.({allowInIframe: true, _debug: 'verbose'})"><\/script>
70689
- <script src="https://unpkg.com/react-grab/dist/index.global.js"><\/script>`;
70690
- function injectScripts(html) {
70691
- return /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (match) => `${match}\n${INJECTED_HEAD}`) : `${INJECTED_HEAD}\n${html}`;
70692
- }
70693
- const proxy = fnUntraced(function* (request, port) {
70694
- const webRequest = yield* toWeb(request);
70695
- const [pathname = "/", search = ""] = request.url.split("?");
70696
- const upstreamHeaders = new Headers(webRequest.headers);
70697
- upstreamHeaders.set("host", `localhost:${port}`);
70698
- const upstreamRequest = new Request(`http://localhost:${port}${pathname}${search ? `?${search}` : ""}`, {
70699
- body: webRequest.body,
70700
- headers: upstreamHeaders,
70701
- method: webRequest.method,
70702
- redirect: webRequest.redirect,
70703
- signal: webRequest.signal
70704
- });
70705
- const upstreamResponse = yield* tryPromise(() => fetch(upstreamRequest));
70706
- const shouldRewriteHtml = request.method === "GET" && (upstreamResponse.headers.get("content-type") ?? "").includes("text/html");
70707
- const headers = new Headers(upstreamResponse.headers);
70708
- headers.delete("content-length");
70709
- headers.delete("content-encoding");
70710
- if (!shouldRewriteHtml) return fromWeb(new Response(upstreamResponse.body, {
70711
- headers,
70712
- status: upstreamResponse.status,
70713
- statusText: upstreamResponse.statusText
70714
- }));
70715
- const body = yield* tryPromise(() => upstreamResponse.text());
70716
- headers.set("content-type", "text/html; charset=utf-8");
70717
- return fromWeb(new Response(injectScripts(body), {
70718
- headers,
70719
- status: upstreamResponse.status,
70720
- statusText: upstreamResponse.statusText
70721
- }));
70722
- });
70723
- const proxyWebSocket = fnUntraced(function* (request, port) {
70724
- const [pathname = "/", search = ""] = request.url.split("?");
70725
- const protocols = request.headers["sec-websocket-protocol"]?.split(",").map((protocol) => protocol.trim()).filter((protocol) => protocol.length > 0);
70726
- const clientSocket = yield* request.upgrade;
70727
- const upstreamSocket = yield* makeWebSocket(`ws://localhost:${port}${pathname}${search ? `?${search}` : ""}`, { protocols }).pipe(provide(layerWebSocketConstructorGlobal));
70728
- const clientWriter = yield* clientSocket.writer;
70729
- const upstreamWriter = yield* upstreamSocket.writer;
70730
- yield* all([clientSocket.runRaw(upstreamWriter), upstreamSocket.runRaw(clientWriter)], { concurrency: "unbounded" }).pipe(scoped$3, catch_$2(() => void_$1));
70731
- return empty();
70732
- });
70733
- function BrowserProxyMiddleware(app) {
70734
- return gen(function* () {
70735
- const request = yield* HttpServerRequest;
70736
- const port = /^(\d+)\.localhost(?::\d+)?$/u.exec(request.headers["host"] ?? "")?.[1];
70737
- if (!port) return yield* app;
70738
- if (request.headers["upgrade"]?.toLowerCase() === "websocket") return yield* proxyWebSocket(request, port);
70739
- return yield* proxy(request, port);
70740
- });
70741
- }
69996
+ const LiveLayers = pipe(empty$11, provideMerge(RpcHandlers), provideMerge(Portless.layer), provideMerge(GitWorkspace.layer), provideMerge(unwrap$4(pipe(string("HOME"), withDefault(process.cwd()), map$4((home) => layerFileSystem(path.join(home, ".deslop")))))), provideMerge(OtelLayer("workbench-server")), provideMerge(layer$16), provideMerge(layerMsgPack));
70742
69997
  //#endregion
70743
69998
  //#region src/main.server.ts
70744
69999
  runMain(pipe(serve(mergeAll$1(layerHttp({
@@ -70749,9 +70004,9 @@ runMain(pipe(serve(mergeAll$1(layerHttp({
70749
70004
  index: "index.html",
70750
70005
  root: fileURLToPath(new URL("./client", import.meta.url)),
70751
70006
  spa: true
70752
- }), middleware(BrowserProxyMiddleware, { global: true }), middleware(xForwardedHeaders, { global: true })), { disableLogger: true }), provide$2(LiveLayers), provide$2(layerConfig(createServer, {
70007
+ }), middleware(Portless.middleware, { global: true }), middleware(xForwardedHeaders, { global: true })), { disableLogger: true }), provide$2(LiveLayers), provide$2(layerConfig(createServer, {
70753
70008
  gracefulShutdownTimeout: succeed("1500 millis"),
70754
- port: port("PORT").pipe(withDefault(4010))
70009
+ port: port("PORT").pipe(withDefault(5010))
70755
70010
  })), provide$2(layer$6), launch));
70756
70011
  //#endregion
70757
70012
  export { __toCommonJS as a, __require as i, init_esm$2 as n, __commonJSMin as r, esm_exports$2 as t };