@homeflare/alchemy 0.59.0 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -385,22 +385,24 @@ before export: every header dropped, every query string stripped, a denylisted h
385
385
  blanked. Options, the redaction policy and what a spike measured actually arriving at a collector:
386
386
  [docs/telemetry.md](./docs/telemetry.md) · [docs/telemetry-spike.md](./docs/telemetry-spike.md).
387
387
 
388
- ## Duplicate resource ids — `@homeflare/alchemy/scope`
388
+ ## Duplicate resource ids — a patch to `alchemy`, `@homeflare/alchemy/scope`
389
389
 
390
390
  ⛔ Two resources of different types declaring the same logical id in one stack scope used to
391
391
  collide silently — Alchemy's own idempotent-registration path treats the second one as a
392
- reference to the first, and the second resource's props never reach a plan. `guardDuplicateIds`
393
- wraps a resource class so a collision dies at registration, naming both types:
394
-
395
- ```ts
396
- import { Resource } from 'alchemy';
397
- import { guardDuplicateIds } from '@homeflare/alchemy/scope';
398
-
399
- export const MyResource = guardDuplicateIds(Resource<MyResource>('My.Resource'));
392
+ reference to the first, and the second resource's props never reach a plan. The fix is a PATCH
393
+ to `alchemy`'s own `Resource.ts` (`patches/alchemy@2.0.0-beta.81.patch`), applied at each
394
+ consuming stack's own root since `alchemy` is a peer dependency here:
395
+
396
+ ```sh
397
+ cp node_modules/@homeflare/alchemy/patches/alchemy@2.0.0-beta.81.patch patches/
398
+ # then add to package.json: "patchedDependencies": { "alchemy@2.0.0-beta.81": "patches/alchemy@2.0.0-beta.81.patch" }
399
+ bun install
400
400
  ```
401
401
 
402
- The measured incident, what this does and does not cover, and the upstream issue proposed for
403
- `alchemy` itself: [docs/duplicate-resource-id.md](./docs/duplicate-resource-id.md).
402
+ `checkAlchemyPatch` (`@homeflare/alchemy/scope`) is what a stack's own `check` calls to catch a
403
+ version bump that silently drops the patch. The measured incident, why a kit-side `Proxy`
404
+ wrapper could not actually fix it, and the upstream issue proposed for `alchemy` itself:
405
+ [docs/duplicate-resource-id.md](./docs/duplicate-resource-id.md).
404
406
 
405
407
  ## Credentials
406
408
 
@@ -28,12 +28,10 @@
28
28
  * place that discharges them — scoped to the handful of effects that actually call
29
29
  * `@distilled.cloud/caddy`'s operations, never leaking into a sibling fetch-based provider merged
30
30
  * into the same stack (admin.ts's own ⛔; MEASURED 2026-09-26, admin-transport-scope.test.ts).
31
- * ⛔ `CaddyConfig` IS WRAPPED IN `guardDuplicateIds` (scope/guard.ts). MEASURED, homeflare-mini PR
32
- * 329: a `NixJobRetirement('caddy', …)` declared in the same stack as this resource's `CADDY_ID
33
- * = 'caddy'` collided silently — Alchemy's own `Resource()` treated the second registration as
34
- * an idempotent re-reference to the first, so the retirement's props were never written
35
- * anywhere a plan could see (`scope/duplicate-id.ts` has the full mechanism). This resource was
36
- * one half of that collision, so it is the first to carry the guard.
31
+ * ⚠️ `CADDY_ID`-style collisions with another resource's id in the same stack (MEASURED,
32
+ * homeflare-mini PR 329: `NixJobRetirement('caddy', …)` beside this resource's own `caddy`)
33
+ * are refused by the patched `alchemy` every consuming stack applies — not by anything in
34
+ * this file. See `packages/alchemy/docs/duplicate-resource-id.md`.
37
35
  */
38
36
  import { Resource } from 'alchemy';
39
37
  import * as Provider from 'alchemy/Provider';
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/caddy/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAK7C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKhF,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAC3C,cAAc,EACd,gBAAgB,EAChB,qBAAqB,CACtB;CAAG;AAEJ,eAAO,MAAM,WAAW,8CAIvB,CAAC;AAoBF,eAAO,MAAM,mBAAmB,oHA+F7B,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/caddy/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKhF,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAC3C,cAAc,EACd,gBAAgB,EAChB,qBAAqB,CACtB;CAAG;AAEJ,eAAO,MAAM,WAAW,8CAEtB,CAAC;AAoBH,eAAO,MAAM,mBAAmB,oHA+F7B,CAAC"}
@@ -169,7 +169,7 @@ import { Resource } from "alchemy";
169
169
  import { Unowned as Unowned2 } from "alchemy/AdoptPolicy";
170
170
  import { isResolved } from "alchemy/Diff";
171
171
  import * as Provider from "alchemy/Provider";
172
- import * as Effect13 from "effect/Effect";
172
+ import * as Effect11 from "effect/Effect";
173
173
 
174
174
  // src/launchd/host-effect.ts
175
175
  import * as Effect2 from "effect/Effect";
@@ -395,88 +395,21 @@ var refuseTakeover = (owner, what) => Effect6.gen(function* () {
395
395
  });
396
396
  var claimFor = (owner) => (what) => refuseTakeover(owner, what);
397
397
 
398
- // src/scope/guard.ts
399
- import * as Effect8 from "effect/Effect";
400
-
401
- // src/scope/duplicate-id.ts
402
- import { toFqn } from "alchemy/FQN";
403
- import { CurrentNamespace } from "alchemy/Namespace";
404
- import { Stack as Stack4 } from "alchemy/Stack";
405
- import * as Data from "effect/Data";
406
- import * as Effect7 from "effect/Effect";
407
-
408
- class DuplicateResourceIdError extends Data.TaggedError("DuplicateResourceIdError") {
409
- }
410
- var scopeLabel = (namespace) => {
411
- if (!namespace)
412
- return "(root)";
413
- const path = [];
414
- let node = namespace;
415
- while (node) {
416
- path.unshift(node.Id);
417
- node = node.Parent;
418
- }
419
- return path.join("/");
420
- };
421
- var registries = new WeakMap;
422
- var registryFor = (stack) => {
423
- const existing = registries.get(stack);
424
- if (existing)
425
- return existing;
426
- const created = new Map;
427
- registries.set(stack, created);
428
- return created;
429
- };
430
- var claimResourceId = (type, id) => Effect7.gen(function* () {
431
- const stack = yield* Stack4;
432
- const namespace = yield* CurrentNamespace;
433
- const fqn = toFqn(namespace, id);
434
- const registry = registryFor(stack);
435
- const firstType = registry.get(fqn);
436
- if (firstType === undefined) {
437
- registry.set(fqn, type);
438
- return;
439
- }
440
- if (firstType !== type) {
441
- return yield* Effect7.die(new DuplicateResourceIdError({
442
- message: `REFUSING: duplicate resource id "${fqn}" in scope ${scopeLabel(namespace)}: ` + `first declared by ${firstType}, again by ${type}`,
443
- fqn,
444
- scope: scopeLabel(namespace),
445
- firstType,
446
- secondType: type
447
- }));
448
- }
449
- });
450
-
451
- // src/scope/guard.ts
452
- var guardDuplicateIds = (resourceClass) => new Proxy(resourceClass, {
453
- apply(target, thisArg, args) {
454
- const id = args[0];
455
- if (typeof id !== "string") {
456
- return Reflect.apply(target, thisArg, args);
457
- }
458
- return Effect8.gen(function* () {
459
- yield* claimResourceId(resourceClass.Type, id);
460
- return yield* Reflect.apply(target, thisArg, args);
461
- });
462
- }
463
- });
464
-
465
398
  // src/caddy/config-lifecycle.ts
466
- import * as Effect11 from "effect/Effect";
399
+ import * as Effect9 from "effect/Effect";
467
400
  import * as Result2 from "effect/Result";
468
401
 
469
402
  // src/caddy/admin-calls.ts
470
- import * as Effect9 from "effect/Effect";
403
+ import * as Effect7 from "effect/Effect";
471
404
  import * as Caddy from "@distilled.cloud/caddy";
472
405
  var CADDYFILE = "text/caddyfile";
473
406
  var describe = (warning) => `${warning.file ?? "Caddyfile"}:${String(warning.line ?? 0)}: ${warning.message ?? "(no message)"}`;
474
- var adaptCaddyfile = (caddyfile) => Effect9.map(Caddy.Services.admin.adaptConfig({ config: caddyfile, contentType: CADDYFILE }), (response) => ({
407
+ var adaptCaddyfile = (caddyfile) => Effect7.map(Caddy.Services.admin.adaptConfig({ config: caddyfile, contentType: CADDYFILE }), (response) => ({
475
408
  config: response.result ?? null,
476
409
  warnings: (response.warnings ?? []).map(describe)
477
410
  }));
478
- var readRunningConfig = () => Effect9.map(Caddy.Services.admin.getConfig({ path: "" }), (response) => response.value ?? null);
479
- var loadCaddyfile = (caddyfile, sourceFile) => Effect9.map(Caddy.Services.admin.loadConfig({
411
+ var readRunningConfig = () => Effect7.map(Caddy.Services.admin.getConfig({ path: "" }), (response) => response.value ?? null);
412
+ var loadCaddyfile = (caddyfile, sourceFile) => Effect7.map(Caddy.Services.admin.loadConfig({
480
413
  config: caddyfile,
481
414
  contentType: CADDYFILE,
482
415
  ...sourceFile === undefined ? {} : { sourceAdapter: "caddyfile", sourceFile }
@@ -561,12 +494,12 @@ var adminProblems = (adapted, transport) => {
561
494
  };
562
495
 
563
496
  // src/caddy/config-errors.ts
564
- import * as Effect10 from "effect/Effect";
497
+ import * as Effect8 from "effect/Effect";
565
498
  var refuse = (endpoint, message) => new Error(`Caddy.Config at ${endpoint}: ${message}`);
566
499
  var short = (digest) => digest.slice(0, 12);
567
500
  var messageOf = (error) => ("message" in error) && typeof error.message === "string" ? error.message : String(error);
568
501
  var operationFailure = (endpoint, op, error) => error._tag === "LoadRefused" ? refuse(endpoint, `Caddy refused the Caddyfile (${error._tag}, a 200 whose body carried the error, not a ` + `failure status) — ${error.message}`) : refuse(endpoint, `${op} failed (${error._tag}) — ${messageOf(error)}`);
569
- var wrapOperation = (endpoint, op) => (effect) => effect.pipe(Effect10.mapError((error) => isUnreachable(error) ? error : operationFailure(endpoint, op, error)));
502
+ var wrapOperation = (endpoint, op) => (effect) => effect.pipe(Effect8.mapError((error) => isUnreachable(error) ? error : operationFailure(endpoint, op, error)));
570
503
 
571
504
  // src/launchd/secret-tripwire.ts
572
505
  var ALTERNATIVE = "props are stored unencrypted in Alchemy state. Have a secret renderer (e.g. openbao-agent) " + "write it to a root-owned file and declare the file path instead (FOO_FILE=/path, --foo-file /path).";
@@ -915,18 +848,18 @@ var servesNothing = (config) => {
915
848
  const apps = typeof config === "object" && config !== null ? config.apps : undefined;
916
849
  return typeof apps !== "object" || apps === null || Object.keys(apps).length === 0;
917
850
  };
918
- var desiredConfig = (props) => Effect11.gen(function* () {
851
+ var desiredConfig = (props) => Effect9.gen(function* () {
919
852
  const { endpoint, listener } = yield* CaddyAdminService;
920
853
  const found = configProblems(props);
921
854
  if (found.length > 0)
922
- return yield* Effect11.fail(refuse(endpoint, found.join("; ")));
855
+ return yield* Effect9.fail(refuse(endpoint, found.join("; ")));
923
856
  const adapted = yield* adaptCaddyfile(props.caddyfile).pipe(wrapOperation(endpoint, "POST /adapt"));
924
857
  if (servesNothing(adapted.config)) {
925
- return yield* Effect11.fail(refuse(endpoint, "the Caddyfile adapts to no apps — loading it would stop every site"));
858
+ return yield* Effect9.fail(refuse(endpoint, "the Caddyfile adapts to no apps — loading it would stop every site"));
926
859
  }
927
860
  const guard = adminProblems(adapted.config, listener);
928
861
  if (guard.length > 0)
929
- return yield* Effect11.fail(refuse(endpoint, guard.join("; ")));
862
+ return yield* Effect9.fail(refuse(endpoint, guard.join("; ")));
930
863
  return { digest: configDigest(adapted.config), warnings: adapted.warnings };
931
864
  });
932
865
  var attributesOf = (endpoint, running, sourceFile) => ({
@@ -934,13 +867,13 @@ var attributesOf = (endpoint, running, sourceFile) => ({
934
867
  endpoint,
935
868
  ...sourceFile === undefined ? {} : { sourceFile }
936
869
  });
937
- var readLive = (sourceFile) => Effect11.gen(function* () {
870
+ var readLive = (sourceFile) => Effect9.gen(function* () {
938
871
  const { endpoint } = yield* CaddyAdminService;
939
872
  const running = yield* readRunningConfig().pipe(wrapOperation(endpoint, "GET /config/"));
940
873
  return attributesOf(endpoint, running, sourceFile);
941
874
  });
942
875
  var claimable = (running, declaredDigest) => servesNothing(running) || configDigest(running) === declaredDigest;
943
- var probeLive = (caddyfile, sourceFile) => Effect11.gen(function* () {
876
+ var probeLive = (caddyfile, sourceFile) => Effect9.gen(function* () {
944
877
  const { endpoint } = yield* CaddyAdminService;
945
878
  const running = yield* readRunningConfig();
946
879
  if (servesNothing(running))
@@ -949,12 +882,12 @@ var probeLive = (caddyfile, sourceFile) => Effect11.gen(function* () {
949
882
  if (caddyfile === undefined) {
950
883
  return { attributes, ours: false, unchecked: "the stored Caddyfile is not plain text" };
951
884
  }
952
- const desired = yield* Effect11.result(desiredConfig({ caddyfile }));
885
+ const desired = yield* Effect9.result(desiredConfig({ caddyfile }));
953
886
  if (Result2.isSuccess(desired)) {
954
887
  return { attributes, ours: claimable(running, desired.success.digest) };
955
888
  }
956
889
  if (isUnreachable(desired.failure))
957
- return yield* Effect11.fail(desired.failure);
890
+ return yield* Effect9.fail(desired.failure);
958
891
  const cause = desired.failure;
959
892
  return {
960
893
  attributes,
@@ -964,7 +897,7 @@ var probeLive = (caddyfile, sourceFile) => Effect11.gen(function* () {
964
897
  });
965
898
 
966
899
  // src/caddy/config-reconcile.ts
967
- import * as Effect12 from "effect/Effect";
900
+ import * as Effect10 from "effect/Effect";
968
901
  import * as Result3 from "effect/Result";
969
902
 
970
903
  // src/caddy/format-warnings.ts
@@ -976,100 +909,100 @@ var splitFormattingWarning = (warnings) => ({
976
909
  var formattingFixLine = (endpoint) => `Caddy.Config at ${endpoint}: Caddyfile is not formatted — run \`caddy fmt\` on it, or format ` + "it with this package's formatCaddyfile() before declaring it, to silence this warning.";
977
910
 
978
911
  // src/caddy/config-reconcile.ts
979
- var diffConfig = (news, output) => Effect12.gen(function* () {
912
+ var diffConfig = (news, output) => Effect10.gen(function* () {
980
913
  const { endpoint } = yield* CaddyAdminService;
981
914
  const want = yield* desiredConfig(news);
982
915
  const { formatting } = splitFormattingWarning(want.warnings);
983
916
  if (formatting.length > 0)
984
- yield* Effect12.logWarning(formattingFixLine(endpoint));
917
+ yield* Effect10.logWarning(formattingFixLine(endpoint));
985
918
  const live = yield* readLive();
986
919
  const converged = want.digest === live.configSha256 && live.configSha256 === output.configSha256 && news.sourceFile === output.sourceFile && endpoint === output.endpoint;
987
920
  return converged ? { action: "noop" } : { action: "update" };
988
921
  });
989
- var reconcileConfig = (props, authority) => Effect12.gen(function* () {
922
+ var reconcileConfig = (props, authority) => Effect10.gen(function* () {
990
923
  const { endpoint } = yield* CaddyAdminService;
991
924
  const want = yield* desiredConfig(props);
992
925
  const running = yield* readRunningConfig().pipe(wrapOperation(endpoint, "GET /config/"));
993
926
  const before = configDigest(running);
994
927
  const known = before === authority.stored || claimable(running, want.digest);
995
928
  if (!authority.takeOver && !known) {
996
- return yield* Effect12.fail(refuse(endpoint, `Caddy runs config ${short(before)}, which this stack did not load, and the Caddyfile ` + `adapts to ${short(want.digest)} — loading it would replace every site that config ` + "serves. Deploy with --adopt (or wrap the resource in adopt(true)) to take this Caddy " + "over, or point caddyProviders() at the Caddy you meant."));
929
+ return yield* Effect10.fail(refuse(endpoint, `Caddy runs config ${short(before)}, which this stack did not load, and the Caddyfile ` + `adapts to ${short(want.digest)} — loading it would replace every site that config ` + "serves. Deploy with --adopt (or wrap the resource in adopt(true)) to take this Caddy " + "over, or point caddyProviders() at the Caddy you meant."));
997
930
  }
998
931
  let warnings = want.warnings;
999
932
  const loaded = before !== want.digest;
1000
933
  if (loaded) {
1001
- const outcome = yield* Effect12.result(loadCaddyfile(props.caddyfile, props.sourceFile));
934
+ const outcome = yield* Effect10.result(loadCaddyfile(props.caddyfile, props.sourceFile));
1002
935
  if (Result3.isFailure(outcome)) {
1003
936
  const error = outcome.failure;
1004
937
  if (isUnreachable(error))
1005
- return yield* Effect12.fail(error);
1006
- const afterRead = yield* Effect12.result(readLive());
938
+ return yield* Effect10.fail(error);
939
+ const afterRead = yield* Effect10.result(readLive());
1007
940
  const after = Result3.isSuccess(afterRead) ? afterRead.success : undefined;
1008
941
  const state = after === undefined ? "and the running config could not be read back" : after.configSha256 === before ? "Caddy kept the previous config (still serving)" : `and the running config is now ${short(after.configSha256)}, not the previous ${short(before)}`;
1009
942
  const reason = error._tag === "LoadRefused" ? `${error.message} (LoadRefused: a 200 whose body carried the error, not a failure status)` : messageOf(error);
1010
- return yield* Effect12.fail(refuse(endpoint, `Caddy refused the Caddyfile — ${reason}; ${state}`));
943
+ return yield* Effect10.fail(refuse(endpoint, `Caddy refused the Caddyfile — ${reason}; ${state}`));
1011
944
  }
1012
945
  warnings = outcome.success;
1013
946
  }
1014
947
  const attributes = yield* readLive(props.sourceFile);
1015
948
  if (attributes.configSha256 !== want.digest) {
1016
- return yield* Effect12.fail(refuse(endpoint, `after the load Caddy runs config ${short(attributes.configSha256)}, not the ` + `${short(want.digest)} this Caddyfile adapts to — another writer changed it, or it was ` + "not applied"));
949
+ return yield* Effect10.fail(refuse(endpoint, `after the load Caddy runs config ${short(attributes.configSha256)}, not the ` + `${short(want.digest)} this Caddyfile adapts to — another writer changed it, or it was ` + "not applied"));
1017
950
  }
1018
951
  return { attributes, loaded, warnings };
1019
952
  });
1020
953
 
1021
954
  // src/caddy/config.ts
1022
- var CaddyConfig = guardDuplicateIds(Resource("Caddy.Config", {
955
+ var CaddyConfig = Resource("Caddy.Config", {
1023
956
  defaultRemovalPolicy: "retain"
1024
- }));
1025
- var planWithoutCaddy = (admin, fallback) => (error) => Effect13.as(Effect13.logWarning(`Caddy.Config: no Caddy at ${admin.endpoint} ` + `(${error instanceof Error ? error.message : String(error)}); planning without it — ` + "the Caddyfile is validated when the deploy reaches Caddy"), fallback);
1026
- var CaddyConfigProvider = () => Provider.effect(CaddyConfig, Effect13.gen(function* () {
957
+ });
958
+ var planWithoutCaddy = (admin, fallback) => (error) => Effect11.as(Effect11.logWarning(`Caddy.Config: no Caddy at ${admin.endpoint} ` + `(${error instanceof Error ? error.message : String(error)}); planning without it — ` + "the Caddyfile is validated when the deploy reaches Caddy"), fallback);
959
+ var CaddyConfigProvider = () => Provider.effect(CaddyConfig, Effect11.gen(function* () {
1027
960
  const admin = yield* CaddyAdminService;
1028
961
  const transportLayer = yield* CaddyAdminTransport;
1029
- const probe = (caddyfile, sourceFile) => Effect13.flatMap(probeLive(caddyfile, sourceFile), (found) => {
962
+ const probe = (caddyfile, sourceFile) => Effect11.flatMap(probeLive(caddyfile, sourceFile), (found) => {
1030
963
  if (found === undefined)
1031
- return Effect13.succeed(undefined);
964
+ return Effect11.succeed(undefined);
1032
965
  if (found.ours)
1033
- return Effect13.succeed(found.attributes);
966
+ return Effect11.succeed(found.attributes);
1034
967
  const unowned = Unowned2(found.attributes);
1035
- return found.unchecked === undefined ? Effect13.succeed(unowned) : Effect13.as(Effect13.logWarning(`Caddy.Config at ${admin.endpoint}: the running config could not be compared ` + `with the declared Caddyfile (${found.unchecked}), so it is not treated as ours`), unowned);
968
+ return found.unchecked === undefined ? Effect11.succeed(unowned) : Effect11.as(Effect11.logWarning(`Caddy.Config at ${admin.endpoint}: the running config could not be compared ` + `with the declared Caddyfile (${found.unchecked}), so it is not treated as ours`), unowned);
1036
969
  });
1037
970
  return CaddyConfig.Provider.of({
1038
- list: () => Effect13.succeed([]),
1039
- read: ({ olds, output }) => Effect13.gen(function* () {
971
+ list: () => Effect11.succeed([]),
972
+ read: ({ olds, output }) => Effect11.gen(function* () {
1040
973
  return output === undefined ? yield* probe(resolvedString(olds, "caddyfile"), resolvedString(olds, "sourceFile")) : yield* readLive(resolvedString(olds, "sourceFile"));
1041
- }).pipe(Effect13.provide(transportLayer), Effect13.catchIf(isUnreachable, planWithoutCaddy(admin, undefined))),
974
+ }).pipe(Effect11.provide(transportLayer), Effect11.catchIf(isUnreachable, planWithoutCaddy(admin, undefined))),
1042
975
  diff: ({ news, output }) => {
1043
976
  if (output === undefined)
1044
- return Effect13.succeed(undefined);
977
+ return Effect11.succeed(undefined);
1045
978
  const update = planWithoutCaddy(admin, { action: "update" });
1046
979
  if (isResolved(news)) {
1047
- return diffConfig(news, output).pipe(Effect13.provide(transportLayer), Effect13.catchIf(isUnreachable, update));
980
+ return diffConfig(news, output).pipe(Effect11.provide(transportLayer), Effect11.catchIf(isUnreachable, update));
1048
981
  }
1049
982
  const caddyfile = resolvedString(news, "caddyfile");
1050
983
  if (caddyfile === undefined)
1051
- return Effect13.succeed(undefined);
1052
- return Effect13.as(diffConfig({ caddyfile }, output), { action: "update" }).pipe(Effect13.provide(transportLayer), Effect13.catchIf(isUnreachable, update));
984
+ return Effect11.succeed(undefined);
985
+ return Effect11.as(diffConfig({ caddyfile }, output), { action: "update" }).pipe(Effect11.provide(transportLayer), Effect11.catchIf(isUnreachable, update));
1053
986
  },
1054
- reconcile: ({ fqn, news, output }) => Effect13.gen(function* () {
987
+ reconcile: ({ fqn, news, output }) => Effect11.gen(function* () {
1055
988
  const sameCaddy = output !== undefined && output.endpoint === admin.endpoint;
1056
989
  const takeOver = sameCaddy || (yield* adoptEnabled(fqn));
1057
990
  const stored = output === undefined ? {} : { stored: output.configSha256 };
1058
- const applied = yield* reconcileConfig(news, { takeOver, ...stored }).pipe(Effect13.provide(transportLayer));
991
+ const applied = yield* reconcileConfig(news, { takeOver, ...stored }).pipe(Effect11.provide(transportLayer));
1059
992
  const { formatting, rest } = splitFormattingWarning(applied.warnings);
1060
993
  if (formatting.length > 0) {
1061
- yield* Effect13.logWarning(formattingFixLine(admin.endpoint));
994
+ yield* Effect11.logWarning(formattingFixLine(admin.endpoint));
1062
995
  }
1063
996
  for (const warning of rest) {
1064
- yield* Effect13.logWarning(`Caddy.Config at ${admin.endpoint}: ${warning}`);
997
+ yield* Effect11.logWarning(`Caddy.Config at ${admin.endpoint}: ${warning}`);
1065
998
  }
1066
999
  return applied.attributes;
1067
1000
  }),
1068
- delete: () => Effect13.void
1001
+ delete: () => Effect11.void
1069
1002
  });
1070
1003
  }));
1071
1004
  // src/caddy/format.ts
1072
- import * as Effect14 from "effect/Effect";
1005
+ import * as Effect12 from "effect/Effect";
1073
1006
  import * as Stream from "effect/Stream";
1074
1007
  import * as ChildProcess from "effect/process/ChildProcess";
1075
1008
  import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
@@ -1096,7 +1029,7 @@ class CaddyFmtFailed extends Error {
1096
1029
  this.name = "CaddyFmtFailed";
1097
1030
  }
1098
1031
  }
1099
- var formatCaddyfile = (text, options = {}) => Effect14.gen(function* () {
1032
+ var formatCaddyfile = (text, options = {}) => Effect12.gen(function* () {
1100
1033
  const binaryPath = options.binaryPath ?? DEFAULT_CADDY_BINARY;
1101
1034
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
1102
1035
  const input = new TextEncoder().encode(text);
@@ -1105,13 +1038,13 @@ var formatCaddyfile = (text, options = {}) => Effect14.gen(function* () {
1105
1038
  stderr: "pipe",
1106
1039
  stdin: Stream.make(input),
1107
1040
  stdout: "pipe"
1108
- }).pipe(spawner.spawn, Effect14.flatMap((child) => Effect14.all({
1041
+ }).pipe(spawner.spawn, Effect12.flatMap((child) => Effect12.all({
1109
1042
  exitCode: child.exitCode,
1110
- stderr: child.stderr.pipe(Stream.decodeText, Stream.mkString, Effect14.map((out) => out.trim())),
1043
+ stderr: child.stderr.pipe(Stream.decodeText, Stream.mkString, Effect12.map((out) => out.trim())),
1111
1044
  stdout: child.stdout.pipe(Stream.decodeText, Stream.mkString)
1112
- }, { concurrency: "unbounded" })), Effect14.scoped, Effect14.catchTag("PlatformError", (error) => error.reason._tag === "NotFound" ? Effect14.fail(new CaddyFmtNotFound(binaryPath, error)) : Effect14.fail(error)));
1045
+ }, { concurrency: "unbounded" })), Effect12.scoped, Effect12.catchTag("PlatformError", (error) => error.reason._tag === "NotFound" ? Effect12.fail(new CaddyFmtNotFound(binaryPath, error)) : Effect12.fail(error)));
1113
1046
  if (result4.exitCode !== 0) {
1114
- return yield* Effect14.fail(new CaddyFmtFailed(binaryPath, result4.exitCode, result4.stderr));
1047
+ return yield* Effect12.fail(new CaddyFmtFailed(binaryPath, result4.exitCode, result4.stderr));
1115
1048
  }
1116
1049
  return result4.stdout;
1117
1050
  });
@@ -1182,7 +1115,7 @@ var localCaddyAdmin = (options = {}) => {
1182
1115
  import * as Layer4 from "effect/Layer";
1183
1116
  var caddyProviders = (transport = localCaddyAdmin()) => CaddyConfigProvider().pipe(Layer4.provideMerge(caddyAdminLayer(transport)));
1184
1117
  // src/caddy/with-file.ts
1185
- import * as Effect16 from "effect/Effect";
1118
+ import * as Effect14 from "effect/Effect";
1186
1119
  import * as RemovalPolicy from "alchemy/RemovalPolicy";
1187
1120
 
1188
1121
  // src/launchd/host-file.ts
@@ -1190,7 +1123,7 @@ import { Resource as Resource2 } from "alchemy";
1190
1123
  import { Unowned as Unowned3 } from "alchemy/AdoptPolicy";
1191
1124
  import { isResolved as isResolved2 } from "alchemy/Diff";
1192
1125
  import * as Provider2 from "alchemy/Provider";
1193
- import * as Effect15 from "effect/Effect";
1126
+ import * as Effect13 from "effect/Effect";
1194
1127
 
1195
1128
  // src/launchd/file-identity.ts
1196
1129
  var sameEntry = (a, b) => {
@@ -1385,10 +1318,10 @@ var deleteFile = (runner, output) => removeWholeFile(runner, output, refuse3);
1385
1318
 
1386
1319
  // src/launchd/host-file.ts
1387
1320
  var HostFile = Resource2("Host.File");
1388
- var HostFileProvider = () => Provider2.effect(HostFile, Effect15.gen(function* () {
1321
+ var HostFileProvider = () => Provider2.effect(HostFile, Effect13.gen(function* () {
1389
1322
  const runner = yield* HostRunnerService;
1390
1323
  return HostFile.Provider.of({
1391
- list: () => Effect15.succeed([]),
1324
+ list: () => Effect13.succeed([]),
1392
1325
  read: ({ olds, output }) => lift(async () => {
1393
1326
  const found = await readFileAttributes(runner, olds.path);
1394
1327
  if (found === undefined)
@@ -1402,19 +1335,19 @@ var HostFileProvider = () => Provider2.effect(HostFile, Effect15.gen(function* (
1402
1335
  return lift(() => diffFile(runner, news, output));
1403
1336
  const path = resolvedString(news, "path");
1404
1337
  if (path === undefined || path === output.path)
1405
- return Effect15.succeed(undefined);
1338
+ return Effect13.succeed(undefined);
1406
1339
  return lift(async () => await oneFile(runner, path, output.path) === true ? undefined : { action: "replace" });
1407
1340
  },
1408
- reconcile: ({ fqn, instanceId, news, output }) => Effect15.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) => lift(() => reconcileFile(runner, news, output, adopt))),
1341
+ reconcile: ({ fqn, instanceId, news, output }) => Effect13.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) => lift(() => reconcileFile(runner, news, output, adopt))),
1409
1342
  delete: ({ output }) => lift(() => deleteFile(runner, output))
1410
1343
  });
1411
1344
  }));
1412
1345
 
1413
1346
  // src/caddy/with-file.ts
1414
- var caddyWithFile = (id, props) => Effect16.gen(function* () {
1347
+ var caddyWithFile = (id, props) => Effect14.gen(function* () {
1415
1348
  const found = configProblems({ caddyfile: props.caddyfile, sourceFile: props.path });
1416
1349
  if (found.length > 0) {
1417
- return yield* Effect16.fail(new Error(`caddyWithFile ${id}: ${found.join("; ")}`));
1350
+ return yield* Effect14.fail(new Error(`caddyWithFile ${id}: ${found.join("; ")}`));
1418
1351
  }
1419
1352
  const file = yield* HostFile(`${id}-file`, {
1420
1353
  content: props.caddyfile,
@@ -1444,5 +1377,5 @@ export {
1444
1377
  verifierProblems
1445
1378
  };
1446
1379
 
1447
- //# debugId=E80D7FC971F2355764756E2164756E21
1380
+ //# debugId=A4890D1A8DCAD67064756E2164756E21
1448
1381
  //# sourceMappingURL=index.js.map