@homeflare/alchemy 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/README.md +74 -41
  2. package/dist/caddy/admin-calls.d.ts +48 -0
  3. package/dist/caddy/admin-calls.d.ts.map +1 -0
  4. package/dist/caddy/admin-guard.d.ts +40 -0
  5. package/dist/caddy/admin-guard.d.ts.map +1 -0
  6. package/dist/caddy/admin.d.ts +73 -0
  7. package/dist/caddy/admin.d.ts.map +1 -0
  8. package/dist/caddy/caddyfile-tripwire.d.ts +5 -0
  9. package/dist/caddy/caddyfile-tripwire.d.ts.map +1 -0
  10. package/dist/caddy/config-form.d.ts +27 -0
  11. package/dist/caddy/config-form.d.ts.map +1 -0
  12. package/dist/caddy/config-lifecycle.d.ts +91 -0
  13. package/dist/caddy/config-lifecycle.d.ts.map +1 -0
  14. package/dist/caddy/config.d.ts +34 -0
  15. package/dist/caddy/config.d.ts.map +1 -0
  16. package/dist/caddy/digest.d.ts +7 -0
  17. package/dist/caddy/digest.d.ts.map +1 -0
  18. package/dist/caddy/fake-caddy.d.ts +54 -0
  19. package/dist/caddy/fake-caddy.d.ts.map +1 -0
  20. package/dist/caddy/index.d.ts +22 -0
  21. package/dist/caddy/index.d.ts.map +1 -0
  22. package/dist/caddy/index.js +970 -0
  23. package/dist/caddy/index.js.map +28 -0
  24. package/dist/caddy/local-admin.d.ts +45 -0
  25. package/dist/caddy/local-admin.d.ts.map +1 -0
  26. package/dist/caddy/providers.d.ts +14 -0
  27. package/dist/caddy/providers.d.ts.map +1 -0
  28. package/dist/caddy/with-file.d.ts +51 -0
  29. package/dist/caddy/with-file.d.ts.map +1 -0
  30. package/dist/cloudflare/fake-mesh.d.ts +58 -0
  31. package/dist/cloudflare/fake-mesh.d.ts.map +1 -0
  32. package/dist/cloudflare/index.d.ts +9 -3
  33. package/dist/cloudflare/index.d.ts.map +1 -1
  34. package/dist/cloudflare/index.js +218 -7
  35. package/dist/cloudflare/index.js.map +9 -4
  36. package/dist/cloudflare/mesh-node-api.d.ts +75 -0
  37. package/dist/cloudflare/mesh-node-api.d.ts.map +1 -0
  38. package/dist/cloudflare/mesh-node-form.d.ts +82 -0
  39. package/dist/cloudflare/mesh-node-form.d.ts.map +1 -0
  40. package/dist/cloudflare/mesh-node-harness.d.ts +46 -0
  41. package/dist/cloudflare/mesh-node-harness.d.ts.map +1 -0
  42. package/dist/cloudflare/mesh-node-lifecycle.d.ts +22 -0
  43. package/dist/cloudflare/mesh-node-lifecycle.d.ts.map +1 -0
  44. package/dist/cloudflare/mesh-node-token.d.ts +23 -0
  45. package/dist/cloudflare/mesh-node-token.d.ts.map +1 -0
  46. package/dist/cloudflare/mesh-node.d.ts +48 -0
  47. package/dist/cloudflare/mesh-node.d.ts.map +1 -0
  48. package/dist/cloudflare/providers.d.ts +1 -12
  49. package/dist/cloudflare/providers.d.ts.map +1 -1
  50. package/dist/index.d.ts +1 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/launchd/fake-sudo.d.ts +50 -0
  53. package/dist/launchd/fake-sudo.d.ts.map +1 -0
  54. package/dist/launchd/host-effect.d.ts +18 -9
  55. package/dist/launchd/host-effect.d.ts.map +1 -1
  56. package/dist/launchd/host-file-form.d.ts +5 -0
  57. package/dist/launchd/host-file-form.d.ts.map +1 -1
  58. package/dist/launchd/host-file-lifecycle.d.ts.map +1 -1
  59. package/dist/launchd/index.d.ts +2 -0
  60. package/dist/launchd/index.d.ts.map +1 -1
  61. package/dist/launchd/index.js +342 -8
  62. package/dist/launchd/index.js.map +16 -12
  63. package/dist/launchd/job-preflight.d.ts.map +1 -1
  64. package/dist/launchd/job-validate.d.ts +2 -0
  65. package/dist/launchd/job-validate.d.ts.map +1 -1
  66. package/dist/launchd/local-runner.d.ts +2 -0
  67. package/dist/launchd/local-runner.d.ts.map +1 -1
  68. package/dist/launchd/providers.d.ts +2 -1
  69. package/dist/launchd/providers.d.ts.map +1 -1
  70. package/dist/launchd/runner.d.ts +7 -5
  71. package/dist/launchd/runner.d.ts.map +1 -1
  72. package/dist/launchd/secret-tripwire.d.ts +1 -0
  73. package/dist/launchd/secret-tripwire.d.ts.map +1 -1
  74. package/dist/launchd/sudo-allowlist.d.ts +47 -0
  75. package/dist/launchd/sudo-allowlist.d.ts.map +1 -0
  76. package/dist/launchd/sudo-guard.d.ts +56 -0
  77. package/dist/launchd/sudo-guard.d.ts.map +1 -0
  78. package/dist/launchd/sudo-runner.d.ts +60 -0
  79. package/dist/launchd/sudo-runner.d.ts.map +1 -0
  80. package/dist/launchd/sudo-stage.d.ts +7 -0
  81. package/dist/launchd/sudo-stage.d.ts.map +1 -0
  82. package/dist/openbao/auth-role-form.d.ts +0 -9
  83. package/dist/openbao/auth-role-form.d.ts.map +1 -1
  84. package/dist/openbao/auth-role.d.ts +3 -2
  85. package/dist/openbao/auth-role.d.ts.map +1 -1
  86. package/dist/openbao/cloudflare-role.d.ts.map +1 -1
  87. package/dist/openbao/fake-engines-roles.d.ts +32 -0
  88. package/dist/openbao/fake-engines-roles.d.ts.map +1 -0
  89. package/dist/openbao/fake-engines.d.ts +36 -0
  90. package/dist/openbao/fake-engines.d.ts.map +1 -0
  91. package/dist/openbao/fake-families.d.ts +49 -0
  92. package/dist/openbao/fake-families.d.ts.map +1 -0
  93. package/dist/openbao/fake-stack.d.ts +29 -0
  94. package/dist/openbao/fake-stack.d.ts.map +1 -0
  95. package/dist/openbao/host-approles.d.ts.map +1 -1
  96. package/dist/openbao/index.js +393 -234
  97. package/dist/openbao/index.js.map +23 -19
  98. package/dist/openbao/jwt-config.d.ts +5 -0
  99. package/dist/openbao/jwt-config.d.ts.map +1 -1
  100. package/dist/openbao/jwt-role.d.ts +2 -1
  101. package/dist/openbao/jwt-role.d.ts.map +1 -1
  102. package/dist/openbao/kubernetes-role.d.ts +2 -1
  103. package/dist/openbao/kubernetes-role.d.ts.map +1 -1
  104. package/dist/openbao/mfa-enforcement.d.ts +6 -3
  105. package/dist/openbao/mfa-enforcement.d.ts.map +1 -1
  106. package/dist/openbao/mfa-totp.d.ts.map +1 -1
  107. package/dist/openbao/pki-role.d.ts.map +1 -1
  108. package/dist/openbao/plugin.d.ts.map +1 -1
  109. package/dist/openbao/policy.d.ts +2 -0
  110. package/dist/openbao/policy.d.ts.map +1 -1
  111. package/dist/openbao/proxmox-role-form.d.ts +18 -8
  112. package/dist/openbao/proxmox-role-form.d.ts.map +1 -1
  113. package/dist/openbao/proxmox-role-wire.d.ts +18 -0
  114. package/dist/openbao/proxmox-role-wire.d.ts.map +1 -0
  115. package/dist/openbao/proxmox-role.d.ts.map +1 -1
  116. package/dist/openbao/rename-identity.d.ts +69 -0
  117. package/dist/openbao/rename-identity.d.ts.map +1 -0
  118. package/dist/openbao/rename.d.ts +107 -0
  119. package/dist/openbao/rename.d.ts.map +1 -0
  120. package/dist/openbao/ssh-role-erase.d.ts +11 -0
  121. package/dist/openbao/ssh-role-erase.d.ts.map +1 -0
  122. package/dist/openbao/ssh-role.d.ts.map +1 -1
  123. package/docs/caddy-admin.md +24 -0
  124. package/docs/caddy.md +199 -0
  125. package/docs/launchd-sudo.md +122 -0
  126. package/docs/launchd.md +7 -4
  127. package/docs/mesh-node.md +188 -0
  128. package/docs/peers.md +39 -0
  129. package/package.json +7 -2
  130. package/src/caddy/admin-calls.ts +128 -0
  131. package/src/caddy/admin-guard.ts +170 -0
  132. package/src/caddy/admin.ts +74 -0
  133. package/src/caddy/adopt-scope.test.ts +82 -0
  134. package/src/caddy/caddyfile-tripwire.ts +133 -0
  135. package/src/caddy/config-adopt.test.ts +235 -0
  136. package/src/caddy/config-form.ts +64 -0
  137. package/src/caddy/config-lifecycle.test.ts +196 -0
  138. package/src/caddy/config-lifecycle.ts +239 -0
  139. package/src/caddy/config.ts +153 -0
  140. package/src/caddy/digest.ts +44 -0
  141. package/src/caddy/fake-caddy.ts +179 -0
  142. package/src/caddy/guards.test.ts +156 -0
  143. package/src/caddy/index.ts +26 -0
  144. package/src/caddy/local-admin.test.ts +160 -0
  145. package/src/caddy/local-admin.ts +189 -0
  146. package/src/caddy/providers.test.ts +229 -0
  147. package/src/caddy/providers.ts +17 -0
  148. package/src/caddy/with-file.ts +66 -0
  149. package/src/cloudflare/fake-mesh.ts +181 -0
  150. package/src/cloudflare/index.ts +9 -3
  151. package/src/cloudflare/mesh-node-api.ts +127 -0
  152. package/src/cloudflare/mesh-node-edges.test.ts +103 -0
  153. package/src/cloudflare/mesh-node-form.test.ts +80 -0
  154. package/src/cloudflare/mesh-node-form.ts +115 -0
  155. package/src/cloudflare/mesh-node-harness.ts +124 -0
  156. package/src/cloudflare/mesh-node-lifecycle.ts +187 -0
  157. package/src/cloudflare/mesh-node-policy.test.ts +151 -0
  158. package/src/cloudflare/mesh-node-token.test.ts +117 -0
  159. package/src/cloudflare/mesh-node-token.ts +125 -0
  160. package/src/cloudflare/mesh-node.test.ts +172 -0
  161. package/src/cloudflare/mesh-node.ts +120 -0
  162. package/src/cloudflare/providers.ts +20 -2
  163. package/src/index.ts +1 -0
  164. package/src/launchd/fake-sudo.ts +136 -0
  165. package/src/launchd/host-effect.ts +33 -1
  166. package/src/launchd/host-file-form.ts +10 -2
  167. package/src/launchd/host-file-lifecycle.ts +2 -1
  168. package/src/launchd/index.ts +2 -0
  169. package/src/launchd/job-preflight.ts +3 -2
  170. package/src/launchd/job-validate.ts +1 -1
  171. package/src/launchd/local-runner.ts +6 -3
  172. package/src/launchd/providers.test.ts +3 -0
  173. package/src/launchd/providers.ts +2 -1
  174. package/src/launchd/runner.ts +7 -5
  175. package/src/launchd/secret-tripwire.ts +1 -1
  176. package/src/launchd/sudo-allowlist.test.ts +191 -0
  177. package/src/launchd/sudo-allowlist.ts +213 -0
  178. package/src/launchd/sudo-guard.test.ts +100 -0
  179. package/src/launchd/sudo-guard.ts +151 -0
  180. package/src/launchd/sudo-lifecycle.test.ts +172 -0
  181. package/src/launchd/sudo-runner-files.test.ts +240 -0
  182. package/src/launchd/sudo-runner.test.ts +126 -0
  183. package/src/launchd/sudo-runner.ts +235 -0
  184. package/src/launchd/sudo-stage.ts +28 -0
  185. package/src/openbao/README.md +8 -2
  186. package/src/openbao/REPLACE.md +126 -22
  187. package/src/openbao/auth-role-form.test.ts +2 -16
  188. package/src/openbao/auth-role-form.ts +0 -11
  189. package/src/openbao/auth-role.ts +35 -14
  190. package/src/openbao/cloudflare-role-wire.test.ts +8 -34
  191. package/src/openbao/cloudflare-role.ts +22 -8
  192. package/src/openbao/fake-engines-roles.ts +114 -0
  193. package/src/openbao/fake-engines.ts +126 -0
  194. package/src/openbao/fake-families.ts +182 -0
  195. package/src/openbao/fake-stack.ts +112 -0
  196. package/src/openbao/host-approles.test.ts +15 -2
  197. package/src/openbao/host-approles.ts +19 -4
  198. package/src/openbao/jwt-config.ts +26 -5
  199. package/src/openbao/jwt-role.ts +24 -8
  200. package/src/openbao/kubernetes-role.ts +20 -8
  201. package/src/openbao/mfa-enforcement.ts +23 -8
  202. package/src/openbao/mfa-totp.ts +21 -8
  203. package/src/openbao/pki-role.ts +19 -7
  204. package/src/openbao/plugin.ts +41 -15
  205. package/src/openbao/policy-rename.test.ts +112 -0
  206. package/src/openbao/policy-wire.test.ts +7 -26
  207. package/src/openbao/policy.ts +27 -4
  208. package/src/openbao/proxmox-role-form.ts +27 -8
  209. package/src/openbao/proxmox-role-wire.ts +24 -0
  210. package/src/openbao/proxmox-role.ts +52 -36
  211. package/src/openbao/rename-adoption.test.ts +82 -0
  212. package/src/openbao/rename-families.test.ts +122 -0
  213. package/src/openbao/rename-identity.test.ts +129 -0
  214. package/src/openbao/rename-identity.ts +117 -0
  215. package/src/openbao/rename-occupied.test.ts +166 -0
  216. package/src/openbao/rename.ts +166 -0
  217. package/src/openbao/role-rename.test.ts +205 -0
  218. package/src/openbao/ssh-role-erase.ts +50 -0
  219. package/src/openbao/ssh-role.ts +16 -54
@@ -0,0 +1,46 @@
1
+ import * as Effect from 'effect/Effect';
2
+ import * as Exit from 'effect/Exit';
3
+ import { type FakeMesh } from './fake-mesh.ts';
4
+ import { MeshNode } from './mesh-node.ts';
5
+ import type { MeshNodeAttributes, MeshNodeProps } from './mesh-node-form.ts';
6
+ export declare const ids: {
7
+ fqn: string;
8
+ id: string;
9
+ instanceId: string;
10
+ };
11
+ export declare const extra: {
12
+ bindings: never;
13
+ session: never;
14
+ };
15
+ export type P = Effect.Success<typeof MeshNode.Provider>;
16
+ export declare const handler: <F>(name: string, fn: F | undefined) => F;
17
+ /** Build the provider over the fake (as `accountId`'s environment) and hand it to `use`. */
18
+ export declare const run: <A, E>(fake: FakeMesh, use: (p: P) => Effect.Effect<A, E>, accountId?: string) => Promise<A>;
19
+ export declare const reconcile: (p: P, news: MeshNodeProps, output?: MeshNodeAttributes) => Effect.Effect<MeshNodeAttributes, any, never>;
20
+ export declare const read: (p: P, olds: MeshNodeProps, output?: MeshNodeAttributes) => Effect.Effect<MeshNodeAttributes | undefined, any, never>;
21
+ export declare const diff: (p: P, news: MeshNodeProps, olds: MeshNodeProps, output: MeshNodeAttributes) => Effect.Effect<void | import("alchemy").Diff, any, never>;
22
+ /** A stored attribute set for a node that may or may not exist in the fake. */
23
+ export declare const stored: (accountId: string, over?: Partial<MeshNodeAttributes>) => MeshNodeAttributes;
24
+ export declare const tokenReads: (fake: FakeMesh) => number;
25
+ /** The writes the fake saw, in order: `['POST', 'DELETE', …]`. */
26
+ export declare const writes: (fake: FakeMesh) => string[];
27
+ /**
28
+ * ★ THE REAL ENGINE, NOT A MODEL OF IT: Alchemy's own `Plan.make` + `apply` over an in-memory
29
+ * state store, which is what its Test harness's scratch stacks run (Test/Core.ts
30
+ * `scratchStack`), minus the profile, config and telemetry layers a fake Cloudflare does not
31
+ * need. Removal policy lives in the engine, so only this can show what it does to a replace.
32
+ * ⚠️ `FetchHttpClient.Fetch` IS READ PER REQUEST, from the fiber running the engine, so it is
33
+ * provided around the whole deploy. Provided only under the provider layer, the requests went
34
+ * to the real `fetch` (measured 2026-09-21: ENOTFOUND api.example.com, the RFC 2606 host, so
35
+ * no API answered — but a real DNS lookup went out).
36
+ */
37
+ export declare const engine: (fake: FakeMesh) => {
38
+ deploy: <A, E, R>(declare: Effect.Effect<A, E, R>) => Promise<Exit.Exit<unknown, unknown>>;
39
+ /** The stored row's status (`created`, `replacing`, …), or `undefined` when there is none. */
40
+ status: (fqn: string) => "created" | "creating" | "deleting" | "replaced" | "replacing" | "updated" | "updating" | undefined;
41
+ /** ★ What `alchemy state rm` does ("Delete state records without deleting cloud resources"). */
42
+ forget: (fqn: string) => void;
43
+ };
44
+ /** The failure sentence of a deploy, or `''` when it succeeded. */
45
+ export declare const failureOf: (exit: Exit.Exit<unknown, unknown>) => string;
46
+ //# sourceMappingURL=mesh-node-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-node-harness.d.ts","sourceRoot":"","sources":["../../src/cloudflare/mesh-node-harness.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AAGpC,OAAO,EAAE,KAAK,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAoB,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7E,eAAO,MAAM,GAAG;IAAK,GAAG;IAAgB,EAAE;IAAU,UAAU;CAAS,CAAC;AACxE,eAAO,MAAM,KAAK;IAAK,QAAQ,EAAQ,KAAK;IAAE,OAAO,EAAe,KAAK;CAAE,CAAC;AAE5E,MAAM,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAEzD,eAAO,MAAM,OAAO,GAAI,CAAC,QAAQ,MAAM,MAAM,CAAC,GAAG,SAAS,KAAG,CAG5D,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,CAAC,QAAQ,QAAQ,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,cAAc,MAAM,eAS7F,CAAC;AAEJ,eAAO,MAAM,SAAS,MAAO,CAAC,QAAQ,aAAa,WAAW,kBAAkB,kDACd,CAAC;AAEnE,eAAO,MAAM,IAAI,MAAO,CAAC,QAAQ,aAAa,WAAW,kBAAkB,8DACxB,CAAC;AAEpD,eAAO,MAAM,IAAI,MAAO,CAAC,QAAQ,aAAa,QAAQ,aAAa,UAAU,kBAAkB,6DAW3F,CAAC;AAEL,+EAA+E;AAC/E,eAAO,MAAM,MAAM,cACN,MAAM,SACX,OAAO,CAAC,kBAAkB,CAAC,KAChC,kBAOD,CAAC;AAEH,eAAO,MAAM,UAAU,SAAU,QAAQ,WACkB,CAAC;AAE5D,kEAAkE;AAClE,eAAO,MAAM,MAAM,SAAU,QAAQ,aAC6B,CAAC;AAInE;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,SAAU,QAAQ;aAInB,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IActD,8FAA8F;kBAChF,MAAM;IACpB,gGAAgG;kBAClF,MAAM;CAIvB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,SAAS,SAAU,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,WACG,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as Effect from 'effect/Effect';
2
+ import { MeshNodeError } from './mesh-node-api.ts';
3
+ import { type MeshNodeAttributes, type MeshNodeProps } from './mesh-node-form.ts';
4
+ /**
5
+ * Owned: refresh by the stored id. Cold: find the live node by exact name and hand it back
6
+ * `Unowned`, so Alchemy refuses to take it over until the stack says `adopt(true)` — the same
7
+ * gate `Cloudflare.Tunnel.WarpConnector` uses, because a `warp_connector` carries no ownership
8
+ * marker to prove it was ours.
9
+ *
10
+ * ⚠️ ADOPTION RECORDS THE DECLARED `ha`, BECAUSE NOTHING ELSE CAN. No documented read returns a
11
+ * node's HA flag. Adopting an existing node with the wrong `ha` records the wrong value, and no
12
+ * later plan can notice. Check the node's HA badge in the dashboard before adopting.
13
+ */
14
+ export declare const readMeshNode: (accountId: string, olds: MeshNodeProps | undefined, output: MeshNodeAttributes | undefined) => Effect.Effect<MeshNodeAttributes | undefined, MeshNodeError | import("@distilled.cloud/cloudflare/zero-trust").ListTunnelWarpConnectorsError, import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
15
+ export declare const reconcileMeshNode: (accountId: string, news: MeshNodeProps, output: MeshNodeAttributes | undefined) => Effect.Effect<MeshNodeAttributes, import("@distilled.cloud/cloudflare/zero-trust").Forbidden | MeshNodeError | import("@distilled.cloud/cloudflare/zero-trust").TunnelNotFound | import("@distilled.cloud/cloudflare/Protocol").CloudflareOpError, import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
16
+ /**
17
+ * ⚠️ Cloudflare may refuse to delete a node while replicas are connected (Alchemy's WarpConnector
18
+ * notes "Deleting requires all connector sessions to be down"; unmeasured here). Stop the
19
+ * client on every replica first. A node already gone is a successful delete.
20
+ */
21
+ export declare const deleteMeshNode: (output: MeshNodeAttributes) => Effect.Effect<void, import("@distilled.cloud/cloudflare/zero-trust").Forbidden | import("@distilled.cloud/cloudflare/Protocol").CloudflareOpError, import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
22
+ //# sourceMappingURL=mesh-node-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-node-lifecycle.d.ts","sourceRoot":"","sources":["../../src/cloudflare/mesh-node-lifecycle.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,aAAa,EAOd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAoB,MAAM,qBAAqB,CAAC;AAUpG;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,cACZ,MAAM,QACX,aAAa,GAAG,SAAS,UACvB,kBAAkB,GAAG,SAAS,sNAapC,CAAC;AAoGL,eAAO,MAAM,iBAAiB,cACjB,MAAM,QACX,aAAa,UACX,kBAAkB,GAAG,SAAS,2TAwBpC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,cAAc,WAAY,kBAAkB,2NAChB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import * as zeroTrust from '@distilled.cloud/cloudflare/zero-trust';
2
+ import * as Effect from 'effect/Effect';
3
+ import * as Redacted from 'effect/Redacted';
4
+ import { MeshNodeError } from './mesh-node-api.ts';
5
+ /** Which node: by id (the `MeshNode` attribute) or by its exact name. */
6
+ export type MeshNodeRef = {
7
+ readonly accountId: string;
8
+ } & ({
9
+ readonly id: string;
10
+ readonly name?: undefined;
11
+ } | {
12
+ readonly name: string;
13
+ readonly id?: undefined;
14
+ });
15
+ /**
16
+ * ⛔ An EMPTY token fails closed: `warp-cli connector new ""` would not enrol, and a script that
17
+ * wrote an empty file would report success over a host that never joined.
18
+ * ⛔ The failures made here name the node and account and quote no response body, because the
19
+ * success body IS the token. Other SDK errors pass through; they come only from non-2xx
20
+ * responses, which carry an error envelope, not a token.
21
+ */
22
+ export declare const fetchMeshNodeToken: (ref: MeshNodeRef) => Effect.Effect<Redacted.Redacted<string>, import("@distilled.cloud/cloudflare/Errors").BadGateway | import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareParseError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/cloudflare/Errors").ConfigError | zeroTrust.Forbidden | import("@distilled.cloud/cloudflare/Errors").GatewayTimeout | import("effect/unstable/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InternalServerError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | MeshNodeError | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | import("@distilled.cloud/cloudflare/Errors").ServiceUnavailable | import("@distilled.cloud/cloudflare/Errors").TooManyRequests | import("@distilled.cloud/cloudflare/Errors").Unauthorized | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError, zeroTrust.CloudflareOpContext>;
23
+ //# sourceMappingURL=mesh-node-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-node-token.d.ts","sourceRoot":"","sources":["../../src/cloudflare/mesh-node-token.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,SAAS,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAkB,MAAM,oBAAoB,CAAC;AAEnE,yEAAyE;AACzE,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,CACvD;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAA;CAAE,CACrD,CAAC;AAoDF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,QAAS,WAAW,wjCA4B/C,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * `Cloudflare.MeshNode` — a Cloudflare Mesh node (a `warp_connector` object), declared without
3
+ * its token ever touching Alchemy state. Usage and the enrolment step: docs/mesh-node.md.
4
+ *
5
+ * 🔴 WHY THIS EXISTS ALONGSIDE `Cloudflare.Tunnel.WarpConnector`. A Mesh node that fronts a
6
+ * private service needs a node record in the graph, so the Gateway rules and DNS records that
7
+ * name it deploy together. Alchemy beta.79's WarpConnector would put the node token — the
8
+ * credential that lets any Linux host join the account's Mesh as that node — into plaintext
9
+ * state on every read, and it cannot create an HA node. See mesh-node-form.ts.
10
+ *
11
+ * ★ REMOVAL POLICY: `retain` BY DEFAULT — see the ★ on `MeshNode` below, and what it does to an
12
+ * `ha` replace in mesh-node-lifecycle.ts.
13
+ */
14
+ import { Credentials } from '@distilled.cloud/cloudflare/Credentials';
15
+ import * as Cloudflare from 'alchemy/Cloudflare';
16
+ import * as Provider from 'alchemy/Provider';
17
+ import { Resource, type ResourceClass } from 'alchemy/Resource';
18
+ import * as HttpClient from 'effect/unstable/http/HttpClient';
19
+ import { type MeshNodeAttributes, type MeshNodeProps } from './mesh-node-form.ts';
20
+ import type { Providers } from './providers.ts';
21
+ export interface MeshNode extends Resource<'Cloudflare.MeshNode', MeshNodeProps, MeshNodeAttributes, never, Providers> {
22
+ }
23
+ /**
24
+ * ★ `defaultRemovalPolicy: 'retain'`, LIKE EVERY KIT RESOURCE WHOSE DELETION BREAKS ITS CONSUMERS
25
+ * (the `Bao.*` families, `R2BucketLock`, the Proxmox storage families; the reasoning is written
26
+ * once in proxmox/resource.ts). Deleting a node cuts every enrolled replica off the Mesh, and
27
+ * nothing brings it back: a new node has a new id, a new token and a new Mesh IP per replica, so
28
+ * each host must be re-enrolled by hand and every Gateway rule or allow-list that pins the old
29
+ * Mesh IP breaks. So dropping the declaration, or `alchemy destroy`, leaves the node live.
30
+ * ⚠️ IT ALSO SKIPS THE OLD NODE'S DELETE IN A REPLACE (Apply.ts, `deleteOldGenerations` and the
31
+ * GC's `retainOldGeneration`, beta.79). A same-name `ha` change therefore REFUSES, deleting
32
+ * nothing, until that deploy opts in with `.pipe(RemovalPolicy.destroy())`; a create-first
33
+ * replace leaves the old node live and unmanaged. Both measured in mesh-node-policy.test.ts.
34
+ * ⛔ `delete` STAYS FULLY IMPLEMENTED. Retain is Terraform's `prevent_destroy`, not a stub: it runs
35
+ * the moment a declaration opts in with `.pipe(RemovalPolicy.destroy())`.
36
+ */
37
+ export declare const MeshNode: ResourceClass<MeshNode>;
38
+ /** What every call below needs: the account, credentials and HTTP — Alchemy's own trio. */
39
+ export type MeshNodeServices = Cloudflare.CloudflareEnvironment | Credentials | HttpClient.HttpClient;
40
+ /**
41
+ * ★ `Provider.effect`, CAPTURING THE THREE SERVICES AT BUILD. `Provider.succeed` (what Alchemy's
42
+ * own providers use) leaves each handler to find CloudflareEnvironment and Credentials in the
43
+ * engine's context at call time — which works for `Cloudflare.providers()` only because it
44
+ * `provideMerge`s them into the stack. Capturing them here keeps this provider correct whether
45
+ * or not the stack also merges `Cloudflare.providers()`.
46
+ */
47
+ export declare const MeshNodeProvider: () => import("effect/Layer").Layer<Provider.Provider<MeshNode>, never, Cloudflare.CloudflareEnvironment | Credentials | HttpClient.HttpClient>;
48
+ //# sourceMappingURL=mesh-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-node.d.ts","sourceRoot":"","sources":["../../src/cloudflare/mesh-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAGnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,QAAS,SAAQ,QAAQ,CACxC,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,KAAK,EACL,SAAS,CACV;CAAG;AAEJ;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAE3C,CAAC;AAEH,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GACxB,UAAU,CAAC,qBAAqB,GAChC,WAAW,GACX,UAAU,CAAC,UAAU,CAAC;AAQ1B;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,gJA4C1B,CAAC"}
@@ -1,19 +1,8 @@
1
- /**
2
- * The HomeFlare Cloudflare provider collection, in the shape `LiteLLM.providers()` has.
3
- *
4
- * ★ ONE LAYER, BUILT ONCE, so the single `Config.Redacted('CLOUDFLARE_API_TOKEN')` read is shared
5
- * by every resource in the stack rather than repeated per resource.
6
- *
7
- * ⚠️ THIS IS NOT `alchemy/Cloudflare`'s COLLECTION AND DOES NOT REPLACE IT. A stack that declares
8
- * both a `Cloudflare.R2.Bucket` and this lock merges the two:
9
- * `Layer.mergeAll(Cloudflare.providers(), HomeflareCloudflare.providers())` — the shape
10
- * a consuming stack names for one talking to more than one account.
11
- */
12
1
  import * as Provider from 'alchemy/Provider';
13
2
  import * as Layer from 'effect/Layer';
14
3
  declare const Providers_base: Provider.ProviderCollection<Providers, "HomeflareCloudflare">;
15
4
  export declare class Providers extends Providers_base {
16
5
  }
17
- export declare const providers: () => Layer.Layer<import("./client.ts").CloudflareApi | Providers, never, never>;
6
+ export declare const providers: () => Layer.Layer<import("./client.ts").CloudflareApi | Providers, never, import("alchemy").AuthProviders | import("effect/unstable/process/ChildProcessSpawner").ChildProcessSpawner | import("effect/Crypto").Crypto | import("effect/FileSystem").FileSystem | import("effect/unstable/http/HttpClient").HttpClient | import("effect/Path").Path>;
18
7
  export {};
19
8
  //# sourceMappingURL=providers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/cloudflare/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;;AAItC,qBAAa,SAAU,SAAQ,cAA+D;CAAG;AAEjG,eAAO,MAAM,SAAS,kFAInB,CAAC"}
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/cloudflare/providers.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;;AAKtC,qBAAa,SAAU,SAAQ,cAA+D;CAAG;AAEjG,eAAO,MAAM,SAAS,sVAWnB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@
10
10
  * import { TalosCluster } from '@homeflare/alchemy/talos';
11
11
  * import { ProxmoxAcl } from '@homeflare/alchemy/proxmox';
12
12
  * import { LaunchdJob } from '@homeflare/alchemy/launchd';
13
+ * import { CaddyConfig } from '@homeflare/alchemy/caddy';
13
14
  *
14
15
  * ★ WHY THESE EXIST AT ALL. When Alchemy has no resource for something, the alternative
15
16
  * is a runbook step a human runs once — and a plan can never show a missing runbook
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { ExecResult, HostRunner } from './runner.ts';
2
+ export declare const OPERATOR = 501;
3
+ export declare const PREFIXES: string[];
4
+ /** What `sudo -n` prints (exit 1) when it will not run the command. Reasoned; see sudo-runner.ts. */
5
+ export declare const SUDO_SAYS: {
6
+ readonly denied: "Sorry, user someone is not allowed to execute '/bin/launchctl bootout system/x' as root on example.\n";
7
+ readonly 'not-in-sudoers': 'someone is not in the sudoers file.\n';
8
+ readonly 'not-on-host': 'someone is not allowed to run sudo on example.\n';
9
+ readonly password: 'sudo: a password is required\n';
10
+ };
11
+ /** `groups` is the operator's `id -G`; `'unknown'` models that lookup failing. */
12
+ export declare const fakeSudoHost: (groups?: readonly number[] | 'unknown', prefixes?: readonly string[]) => {
13
+ fake: {
14
+ calls: string[][];
15
+ disabled: Set<string>;
16
+ dirs: Map<string, number>;
17
+ files: Map<string, {
18
+ bytes: Uint8Array;
19
+ mode: number;
20
+ uid: number;
21
+ gid: number;
22
+ kind: import("./runner.ts").FileStat['kind'];
23
+ }>;
24
+ loaded: Map<string, number | undefined>;
25
+ runner: HostRunner;
26
+ state: {
27
+ lingerPrints: number;
28
+ nextPid: number;
29
+ bootstrapFailure: ExecResult | undefined;
30
+ bootoutFailure: ExecResult | undefined;
31
+ bootoutKeepsJob: boolean;
32
+ loggedOut: Set<number>;
33
+ };
34
+ };
35
+ logs: string[];
36
+ privileged: () => string[][];
37
+ runner: HostRunner;
38
+ staged: Map<string, Uint8Array<ArrayBufferLike>>;
39
+ state: {
40
+ /** What sudo itself answers: runs the command, or refuses it with one of SUDO_SAYS. */
41
+ sudo: 'ok' | keyof typeof SUDO_SAYS;
42
+ /** Returned by `install` in place of success; nothing is written. */
43
+ installFailure: ExecResult | undefined;
44
+ stagedCount: number;
45
+ /** The staged bytes as `install` saw them, by destination. */
46
+ installedFrom: Map<string, string>;
47
+ };
48
+ sudoCalls: string[][];
49
+ };
50
+ //# sourceMappingURL=fake-sudo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-sudo.d.ts","sourceRoot":"","sources":["../../src/launchd/fake-sudo.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI1D,eAAO,MAAM,QAAQ,MAAM,CAAC;AAC5B,eAAO,MAAM,QAAQ,UAA6C,CAAC;AAInE,qGAAqG;AACrG,eAAO,MAAM,SAAS;aACpB,MAAM,EACJ,uGAAuG;aACzG,gBAAgB,EAAE,uCAAuC;aACzD,aAAa,EAAE,kDAAkD;aACjE,QAAQ,EAAE,gCAAgC;CAClC,CAAC;AAoBX,kFAAkF;AAClF,eAAO,MAAM,YAAY,YACf,SAAS,MAAM,EAAE,GAAG,SAAS,aAC3B,SAAS,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAsBzB,uFAAuF;cACzE,IAAI,GAAG,MAAM,OAAO,SAAS;QAC3C,qEAAqE;wBACxC,UAAU,GAAG,SAAS;;QAEnD,8DAA8D;;;;CAqDjE,CAAC"}
@@ -1,12 +1,3 @@
1
- /**
2
- * The one place a HostRunner's promises become Effects — plus the one probe of an unresolved
3
- * `news` both providers' diffs share.
4
- *
5
- * ★ The lifecycle files are plain async functions over a HostRunner (see runner.ts for why the
6
- * runner is promise-based), so each provider handler is a single `lift(() => step(runner, …))`.
7
- * ⚠️ A thrown Error stays that Error — its message is the refusal a deploy prints. Anything else
8
- * thrown is wrapped, so the failure channel is always an Error with a readable message.
9
- */
10
1
  import * as Effect from 'effect/Effect';
11
2
  export declare const lift: <A>(step: () => Promise<A>) => Effect.Effect<A, Error>;
12
3
  /**
@@ -16,4 +7,22 @@ export declare const lift: <A>(step: () => Promise<A>) => Effect.Effect<A, Error
16
7
  * string is resolved by definition, so `typeof` is the whole test.
17
8
  */
18
9
  export declare const resolvedString: (news: unknown, key: string) => string | undefined;
10
+ /**
11
+ * Whether the resource at `fqn` may be adopted, resolved exactly as the planner resolves it (alchemy
12
+ * beta.79 Plan.ts: `resource.Adopt ?? shouldAdopt`): a resource-scoped `adopt(…)`, else the
13
+ * `AdoptPolicy` service, else `AlchemyContext.adopt`, else off.
14
+ * ★ FOR A CREATE THE ENGINE NEVER PROBED. Alchemy skips the adoption probe while `news` holds an
15
+ * Output, so an ownership check that must still honour `--adopt` can only run at apply. All three
16
+ * reach the apply: Alchemist runs plan AND apply under the session context, which provides the
17
+ * services from the CLI flag and the Stack the resources registered on (Alchemist/Session.ts,
18
+ * routes/stack.ts; Apply.ts reads the same Stack).
19
+ * ⛔ THE RESOURCE-SCOPED SETTING WINS, BOTH WAYS. The engine captures `adopt(…)` on the resource at
20
+ * registration (Resource.ts `Adopt`, into `Stack.resources[fqn]`) and never hands it to a
21
+ * provider. Reading only the deploy-wide flag let `--adopt` take over a resource declared
22
+ * `.pipe(adopt(false))` — which the planner refuses — and refused one declared `adopt(true)`.
23
+ * ⚠️ `resources` carries an `@internal` comment in Alchemy's source, but it is in the published types
24
+ * and the planner reads `Adopt` from it. caddy/adopt-scope.test.ts registers through the real
25
+ * `Resource`, so an upgrade that stops recording it there fails the suite.
26
+ */
27
+ export declare const adoptEnabled: (fqn: string) => Effect.Effect<boolean>;
19
28
  //# sourceMappingURL=host-effect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-effect.d.ts","sourceRoot":"","sources":["../../src/launchd/host-effect.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,eAAO,MAAM,IAAI,GAAI,CAAC,QAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAInE,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAAU,OAAO,OAAO,MAAM,KAAG,MAAM,GAAG,SAIpE,CAAC"}
1
+ {"version":3,"file":"host-effect.d.ts","sourceRoot":"","sources":["../../src/launchd/host-effect.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,eAAO,MAAM,IAAI,GAAI,CAAC,QAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAInE,CAAC;AAEL;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAAU,OAAO,OAAO,MAAM,KAAG,MAAM,GAAG,SAIpE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAS5D,CAAC"}
@@ -20,5 +20,10 @@ export interface HostFileAttributes {
20
20
  size: number;
21
21
  }
22
22
  export declare const DEFAULT_MODE = 420;
23
+ /**
24
+ * An absolute, normalised path, or the reasons it is not. ★ Shared with sudo-allowlist.ts, so a
25
+ * path the sudo runner may touch as root obeys exactly the rule a declared file does.
26
+ */
27
+ export declare const pathProblems: (path: string) => string[];
23
28
  export declare const fileProblems: (props: HostFileProps) => string[];
24
29
  //# sourceMappingURL=host-file-form.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-file-form.d.ts","sourceRoot":"","sources":["../../src/launchd/host-file-form.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,YAAY,MAAQ,CAAC;AAclC,eAAO,MAAM,YAAY,UAAW,aAAa,KAAG,MAAM,EAsBzD,CAAC"}
1
+ {"version":3,"file":"host-file-form.d.ts","sourceRoot":"","sources":["../../src/launchd/host-file-form.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,YAAY,MAAQ,CAAC;AAclC;;;GAGG;AACH,eAAO,MAAM,YAAY,SAAU,MAAM,KAAG,MAAM,EAgBjD,CAAC;AAEF,eAAO,MAAM,YAAY,UAAW,aAAa,KAAG,MAAM,EAQzD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"host-file-lifecycle.d.ts","sourceRoot":"","sources":["../../src/launchd/host-file-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,aAAa,CAAC;AAE5D,KAAK,OAAO,GAAG;IACb,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAOF,0EAA0E;AAC1E,eAAO,MAAM,WAAW,WAAkB,UAAU,SAAS,aAAa,KAAG,OAAO,CAAC,OAAO,CAqB3F,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,WACrB,UAAU,QACZ,MAAM,KACX,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAYxC,CAAC;AAQF,eAAO,MAAM,QAAQ,WACX,UAAU,QACZ,aAAa,UACX,kBAAkB,KACzB,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,eAAO,MAAM,aAAa,WAChB,UAAU,SACX,aAAa,WACX,kBAAkB,KAC1B,OAAO,CAAC,kBAAkB,CA0D5B,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,UAAU,WAAkB,UAAU,UAAU,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAK7F,CAAC"}
1
+ {"version":3,"file":"host-file-lifecycle.d.ts","sourceRoot":"","sources":["../../src/launchd/host-file-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,aAAa,CAAC;AAE5D,KAAK,OAAO,GAAG;IACb,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAOF,0EAA0E;AAC1E,eAAO,MAAM,WAAW,WAAkB,UAAU,SAAS,aAAa,KAAG,OAAO,CAAC,OAAO,CAqB3F,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,WACrB,UAAU,QACZ,MAAM,KACX,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAYxC,CAAC;AAQF,eAAO,MAAM,QAAQ,WACX,UAAU,QACZ,aAAa,UACX,kBAAkB,KACzB,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,eAAO,MAAM,aAAa,WAChB,UAAU,SACX,aAAa,WACX,kBAAkB,KAC1B,OAAO,CAAC,kBAAkB,CA2D5B,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,UAAU,WAAkB,UAAU,UAAU,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAK7F,CAAC"}
@@ -18,4 +18,6 @@ export { PlistError, renderPlist } from './plist.ts';
18
18
  export { launchdProviders } from './providers.ts';
19
19
  export type { ExecResult, FileStat, HostRunner, HostUser, WriteOptions } from './runner.ts';
20
20
  export { HostRunnerService, canActAsRoot, hostRunnerLayer } from './runner.ts';
21
+ export type { SudoRunnerOptions } from './sudo-runner.ts';
22
+ export { SudoRefusedError, sudoRunner } from './sudo-runner.ts';
21
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/launchd/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/launchd/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,eAAe,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC/E,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}