@homeflare/alchemy 0.11.0 → 0.13.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 (290) hide show
  1. package/README.md +3 -3
  2. package/dist/caddy/admin-guard.d.ts +1 -1
  3. package/dist/caddy/index.js.map +2 -2
  4. package/dist/cloudflare/client.d.ts +1 -1
  5. package/dist/cloudflare/index.js.map +2 -2
  6. package/dist/cloudflare/lock-rules.d.ts +1 -1
  7. package/dist/forgejo/branch-protection-form.d.ts +1 -1
  8. package/dist/forgejo/branch-protection.d.ts +1 -1
  9. package/dist/forgejo/index.js.map +10 -10
  10. package/dist/forgejo/org-actions-secrets.d.ts +1 -1
  11. package/dist/forgejo/org-label.d.ts +1 -1
  12. package/dist/forgejo/org-team.d.ts +1 -1
  13. package/dist/forgejo/repo-webhook.d.ts +1 -1
  14. package/dist/forgejo/repository.d.ts +2 -2
  15. package/dist/forgejo/repository.d.ts.map +1 -1
  16. package/dist/forgejo/resource.d.ts +2 -2
  17. package/dist/forgejo/team-member.d.ts +1 -1
  18. package/dist/openbao/auth-role.d.ts +1 -1
  19. package/dist/openbao/bao-http.d.ts +4 -4
  20. package/dist/openbao/cloudflare-permission-groups.d.ts +1 -1
  21. package/dist/openbao/cloudflare-role-form.d.ts +2 -2
  22. package/dist/openbao/cloudflare-role-form.d.ts.map +1 -1
  23. package/dist/openbao/cloudflare-roles-expand.d.ts +1 -1
  24. package/dist/openbao/digest.d.ts +1 -1
  25. package/dist/openbao/forgejo-bootstrap-parse.d.ts +2 -2
  26. package/dist/openbao/forgejo-bootstrap-parse.d.ts.map +1 -1
  27. package/dist/openbao/forgejo-bootstrap.d.ts +1 -1
  28. package/dist/openbao/index.js.map +14 -14
  29. package/dist/openbao/mount.d.ts +1 -1
  30. package/dist/openbao/pki-role.d.ts +1 -1
  31. package/dist/openbao/policy.d.ts +2 -2
  32. package/dist/openbao/proxmox-role-form.d.ts +2 -2
  33. package/dist/openbao/proxmox-role-form.d.ts.map +1 -1
  34. package/dist/openbao/proxmox-role.d.ts +10 -10
  35. package/dist/openbao/ssh-role.d.ts +3 -3
  36. package/dist/proxmox/acl.d.ts +2 -2
  37. package/dist/proxmox/acl.d.ts.map +1 -1
  38. package/dist/proxmox/alertmanager-body.d.ts +54 -0
  39. package/dist/proxmox/alertmanager-body.d.ts.map +1 -0
  40. package/dist/proxmox/api-token-form.d.ts +2 -2
  41. package/dist/proxmox/api-token.d.ts +11 -11
  42. package/dist/proxmox/ceph-daemon-form.d.ts +3 -3
  43. package/dist/proxmox/ceph-daemon.d.ts +19 -19
  44. package/dist/proxmox/ceph-daemon.d.ts.map +1 -1
  45. package/dist/proxmox/ceph-flag.d.ts +5 -5
  46. package/dist/proxmox/ceph-fs-wire.d.ts +5 -5
  47. package/dist/proxmox/ceph-fs.d.ts +16 -16
  48. package/dist/proxmox/ceph-osd-tree.d.ts +16 -16
  49. package/dist/proxmox/ceph-osd.d.ts +5 -5
  50. package/dist/proxmox/ceph-pool-form.d.ts +13 -13
  51. package/dist/proxmox/ceph-pool-form.d.ts.map +1 -1
  52. package/dist/proxmox/ceph-pool.d.ts +3 -3
  53. package/dist/proxmox/client.d.ts +2 -2
  54. package/dist/proxmox/credential-literals.d.ts +36 -0
  55. package/dist/proxmox/credential-literals.d.ts.map +1 -0
  56. package/dist/proxmox/credentials.d.ts +8 -8
  57. package/dist/proxmox/credentials.d.ts.map +1 -1
  58. package/dist/proxmox/fake-pbs-notify.d.ts +23 -0
  59. package/dist/proxmox/fake-pbs-notify.d.ts.map +1 -0
  60. package/dist/proxmox/fake-pve.d.ts +5 -0
  61. package/dist/proxmox/fake-pve.d.ts.map +1 -1
  62. package/dist/proxmox/firewall-alias-form.d.ts +1 -1
  63. package/dist/proxmox/firewall-alias.d.ts +1 -1
  64. package/dist/proxmox/generated/pbs.d.ts +279 -1
  65. package/dist/proxmox/generated/pbs.d.ts.map +1 -1
  66. package/dist/proxmox/generated/pve.d.ts +58 -1
  67. package/dist/proxmox/generated/pve.d.ts.map +1 -1
  68. package/dist/proxmox/group.d.ts +8 -8
  69. package/dist/proxmox/ha-resource.d.ts +3 -2
  70. package/dist/proxmox/ha-resource.d.ts.map +1 -1
  71. package/dist/proxmox/ha-rule-form.d.ts +5 -5
  72. package/dist/proxmox/ha-rule.d.ts +3 -3
  73. package/dist/proxmox/index.d.ts +14 -0
  74. package/dist/proxmox/index.d.ts.map +1 -1
  75. package/dist/proxmox/index.js +935 -223
  76. package/dist/proxmox/index.js.map +69 -56
  77. package/dist/proxmox/lease-cache.d.ts +4 -4
  78. package/dist/proxmox/lxc-harness.d.ts +1 -1
  79. package/dist/proxmox/lxc-props.d.ts +2 -2
  80. package/dist/proxmox/lxc.d.ts +3 -3
  81. package/dist/proxmox/members.d.ts +3 -3
  82. package/dist/proxmox/network-apply-read.d.ts +5 -5
  83. package/dist/proxmox/network-apply.d.ts +9 -9
  84. package/dist/proxmox/node-network-form.d.ts +6 -6
  85. package/dist/proxmox/node-network.d.ts +17 -17
  86. package/dist/proxmox/node-network.d.ts.map +1 -1
  87. package/dist/proxmox/notification-matcher-form.d.ts +100 -0
  88. package/dist/proxmox/notification-matcher-form.d.ts.map +1 -0
  89. package/dist/proxmox/notification-matcher.d.ts +46 -0
  90. package/dist/proxmox/notification-matcher.d.ts.map +1 -0
  91. package/dist/proxmox/notification-target.d.ts +3 -2
  92. package/dist/proxmox/notification-target.d.ts.map +1 -1
  93. package/dist/proxmox/pbs-datastore-guard.d.ts +1 -1
  94. package/dist/proxmox/pbs-datastore.d.ts +10 -10
  95. package/dist/proxmox/pbs-notification-matcher.d.ts +53 -0
  96. package/dist/proxmox/pbs-notification-matcher.d.ts.map +1 -0
  97. package/dist/proxmox/pbs-notification-target-form.d.ts +63 -0
  98. package/dist/proxmox/pbs-notification-target-form.d.ts.map +1 -0
  99. package/dist/proxmox/pbs-notification-target-lifecycle.d.ts +100 -0
  100. package/dist/proxmox/pbs-notification-target-lifecycle.d.ts.map +1 -0
  101. package/dist/proxmox/pbs-notification-target-wire.d.ts +30 -0
  102. package/dist/proxmox/pbs-notification-target-wire.d.ts.map +1 -0
  103. package/dist/proxmox/pbs-notification-target.d.ts +123 -0
  104. package/dist/proxmox/pbs-notification-target.d.ts.map +1 -0
  105. package/dist/proxmox/pbs-prune-job.d.ts +2 -2
  106. package/dist/proxmox/pbs-sync-job.d.ts +4 -4
  107. package/dist/proxmox/pbs-verify-job.d.ts +1 -1
  108. package/dist/proxmox/pool.d.ts +4 -4
  109. package/dist/proxmox/provision-baseline.d.ts +74 -0
  110. package/dist/proxmox/provision-baseline.d.ts.map +1 -0
  111. package/dist/proxmox/provision-bootstrap.d.ts +33 -0
  112. package/dist/proxmox/provision-bootstrap.d.ts.map +1 -0
  113. package/dist/proxmox/provision-cli-fake.d.ts +38 -0
  114. package/dist/proxmox/provision-cli-fake.d.ts.map +1 -0
  115. package/dist/proxmox/provision-declare.d.ts +25 -0
  116. package/dist/proxmox/provision-declare.d.ts.map +1 -0
  117. package/dist/proxmox/replication-job.d.ts +9 -8
  118. package/dist/proxmox/replication-job.d.ts.map +1 -1
  119. package/dist/proxmox/resource.d.ts +6 -5
  120. package/dist/proxmox/resource.d.ts.map +1 -1
  121. package/dist/proxmox/sdn-apply-read.d.ts +7 -7
  122. package/dist/proxmox/sdn-apply.d.ts +1 -1
  123. package/dist/proxmox/sdn-subnet-form.d.ts +1 -1
  124. package/dist/proxmox/sdn-subnet.d.ts +5 -5
  125. package/dist/proxmox/sdn-vnet.d.ts +5 -6
  126. package/dist/proxmox/sdn-vnet.d.ts.map +1 -1
  127. package/dist/proxmox/storage.d.ts +4 -3
  128. package/dist/proxmox/storage.d.ts.map +1 -1
  129. package/dist/proxmox/user.d.ts +3 -2
  130. package/dist/proxmox/user.d.ts.map +1 -1
  131. package/dist/proxmox/values.d.ts +1 -1
  132. package/dist/proxmox/write-only.d.ts +35 -0
  133. package/dist/proxmox/write-only.d.ts.map +1 -0
  134. package/dist/proxmox/zfs-pool-write.d.ts +1 -1
  135. package/dist/proxmox/zfs-pool.d.ts +5 -5
  136. package/dist/talos/credentials.d.ts +1 -1
  137. package/dist/talos/credentials.d.ts.map +1 -1
  138. package/dist/talos/index.js.map +1 -1
  139. package/dist/verify/fake-engine.d.ts +5 -0
  140. package/dist/verify/fake-engine.d.ts.map +1 -1
  141. package/docs/adopt-verify.md +21 -5
  142. package/docs/adopted-deploys.md +9 -1
  143. package/docs/ownership.md +26 -1
  144. package/docs/pbs-alertmanager-body.md +73 -0
  145. package/docs/pbs-notifications.md +163 -0
  146. package/docs/provision-baseline.md +106 -0
  147. package/docs/proxmox-lxc-adopt.md +2 -2
  148. package/docs/proxmox-lxc.md +5 -4
  149. package/docs/proxmox.md +9 -0
  150. package/package.json +1 -1
  151. package/src/caddy/admin-guard.ts +1 -1
  152. package/src/caddy/local-admin.ts +1 -1
  153. package/src/cloudflare/client.ts +1 -1
  154. package/src/cloudflare/lock-rules.ts +1 -1
  155. package/src/forgejo/branch-protection-form.ts +1 -1
  156. package/src/forgejo/branch-protection.ts +1 -1
  157. package/src/forgejo/client.ts +1 -1
  158. package/src/forgejo/org-actions-secrets.ts +1 -1
  159. package/src/forgejo/org-label.ts +1 -1
  160. package/src/forgejo/org-team.ts +1 -1
  161. package/src/forgejo/repo-webhook.ts +1 -1
  162. package/src/forgejo/repository.ts +2 -2
  163. package/src/forgejo/resource.ts +2 -2
  164. package/src/forgejo/team-member.ts +1 -1
  165. package/src/openbao/README.md +4 -4
  166. package/src/openbao/auth-role.ts +1 -1
  167. package/src/openbao/bao-http.test.ts +2 -2
  168. package/src/openbao/bao-http.ts +6 -6
  169. package/src/openbao/bao-status.test.ts +1 -1
  170. package/src/openbao/bao-status.ts +1 -1
  171. package/src/openbao/cloudflare-group-scope.test.ts +1 -1
  172. package/src/openbao/cloudflare-permission-groups.test.ts +1 -1
  173. package/src/openbao/cloudflare-permission-groups.ts +3 -3
  174. package/src/openbao/cloudflare-policy.ts +1 -1
  175. package/src/openbao/cloudflare-role-form.ts +2 -2
  176. package/src/openbao/cloudflare-roles-expand.ts +1 -1
  177. package/src/openbao/digest.ts +1 -1
  178. package/src/openbao/forgejo-bootstrap-parse.test.ts +3 -3
  179. package/src/openbao/forgejo-bootstrap-parse.ts +2 -2
  180. package/src/openbao/forgejo-bootstrap.ts +4 -4
  181. package/src/openbao/kubernetes-role-form.test.ts +5 -5
  182. package/src/openbao/mount.ts +1 -1
  183. package/src/openbao/pki-role.ts +1 -1
  184. package/src/openbao/policy-wire.test.ts +3 -3
  185. package/src/openbao/policy.ts +2 -2
  186. package/src/openbao/proxmox-role-form.ts +5 -5
  187. package/src/openbao/proxmox-role.ts +11 -11
  188. package/src/openbao/ssh-role.ts +3 -3
  189. package/src/proxmox/acl.ts +4 -4
  190. package/src/proxmox/adopt-noop.test.ts +6 -6
  191. package/src/proxmox/alertmanager-body.ts +125 -0
  192. package/src/proxmox/api-token-form.ts +4 -4
  193. package/src/proxmox/api-token.ts +13 -13
  194. package/src/proxmox/ceph-daemon-form.ts +3 -3
  195. package/src/proxmox/ceph-daemon.ts +20 -20
  196. package/src/proxmox/ceph-flag.ts +7 -7
  197. package/src/proxmox/ceph-fs-wire.ts +7 -7
  198. package/src/proxmox/ceph-fs.ts +18 -18
  199. package/src/proxmox/ceph-osd-tree.ts +16 -16
  200. package/src/proxmox/ceph-osd.ts +6 -6
  201. package/src/proxmox/ceph-pool-adopt.test.ts +14 -14
  202. package/src/proxmox/ceph-pool-form.ts +13 -13
  203. package/src/proxmox/ceph-pool.ts +6 -6
  204. package/src/proxmox/client.test.ts +3 -3
  205. package/src/proxmox/client.ts +3 -3
  206. package/src/proxmox/credential-literals.test.ts +148 -0
  207. package/src/proxmox/credential-literals.ts +74 -0
  208. package/src/proxmox/credentials.test.ts +6 -8
  209. package/src/proxmox/credentials.ts +8 -8
  210. package/src/proxmox/fake-pbs-notify.ts +108 -0
  211. package/src/proxmox/fake-pve.ts +12 -2
  212. package/src/proxmox/firewall-alias-form.ts +1 -1
  213. package/src/proxmox/firewall-alias.ts +1 -1
  214. package/src/proxmox/generated/pbs.ts +330 -1
  215. package/src/proxmox/generated/pve.ts +63 -1
  216. package/src/proxmox/group.ts +10 -10
  217. package/src/proxmox/ha-resource.ts +3 -2
  218. package/src/proxmox/ha-rule-form.ts +5 -5
  219. package/src/proxmox/ha-rule.ts +3 -3
  220. package/src/proxmox/index.test.ts +10 -0
  221. package/src/proxmox/index.ts +32 -0
  222. package/src/proxmox/lease-cache.test.ts +19 -19
  223. package/src/proxmox/lease-cache.ts +4 -4
  224. package/src/proxmox/lxc-adopt.test.ts +3 -3
  225. package/src/proxmox/lxc-create-form.ts +1 -1
  226. package/src/proxmox/lxc-guards.test.ts +4 -4
  227. package/src/proxmox/lxc-harness.ts +3 -3
  228. package/src/proxmox/lxc-judge.test.ts +5 -5
  229. package/src/proxmox/lxc-lifecycle.ts +1 -1
  230. package/src/proxmox/lxc-props.ts +2 -2
  231. package/src/proxmox/lxc-read.test.ts +3 -3
  232. package/src/proxmox/lxc-strict-adopt.test.ts +1 -1
  233. package/src/proxmox/lxc-volume.test.ts +9 -9
  234. package/src/proxmox/lxc-volume.ts +1 -1
  235. package/src/proxmox/lxc-wire.ts +1 -1
  236. package/src/proxmox/lxc.ts +3 -3
  237. package/src/proxmox/members.test.ts +1 -1
  238. package/src/proxmox/members.ts +3 -3
  239. package/src/proxmox/metric-server-otel.ts +2 -2
  240. package/src/proxmox/network-apply-read.ts +10 -10
  241. package/src/proxmox/network-apply.ts +10 -10
  242. package/src/proxmox/node-network-form.ts +7 -7
  243. package/src/proxmox/node-network.ts +18 -18
  244. package/src/proxmox/notification-matcher-form.ts +221 -0
  245. package/src/proxmox/notification-matcher.test.ts +234 -0
  246. package/src/proxmox/notification-matcher.ts +76 -0
  247. package/src/proxmox/notification-target.ts +3 -2
  248. package/src/proxmox/pbs-datastore-guard.ts +1 -1
  249. package/src/proxmox/pbs-datastore.ts +10 -10
  250. package/src/proxmox/pbs-notification-matcher.ts +81 -0
  251. package/src/proxmox/pbs-notification-target-drift.test.ts +83 -0
  252. package/src/proxmox/pbs-notification-target-form.ts +229 -0
  253. package/src/proxmox/pbs-notification-target-lifecycle.ts +177 -0
  254. package/src/proxmox/pbs-notification-target-state.test.ts +191 -0
  255. package/src/proxmox/pbs-notification-target-wire.ts +112 -0
  256. package/src/proxmox/pbs-notification-target.test.ts +226 -0
  257. package/src/proxmox/pbs-notification-target.ts +139 -0
  258. package/src/proxmox/pbs-notifications-stack.test.ts +94 -0
  259. package/src/proxmox/pbs-prune-job.ts +2 -2
  260. package/src/proxmox/pbs-sync-job.ts +4 -4
  261. package/src/proxmox/pbs-verify-job.ts +1 -1
  262. package/src/proxmox/pool.test.ts +2 -2
  263. package/src/proxmox/pool.ts +4 -4
  264. package/src/proxmox/provision-baseline.test.ts +87 -0
  265. package/src/proxmox/provision-baseline.ts +162 -0
  266. package/src/proxmox/provision-bootstrap.test.ts +132 -0
  267. package/src/proxmox/provision-bootstrap.ts +135 -0
  268. package/src/proxmox/provision-cli-fake.ts +217 -0
  269. package/src/proxmox/provision-declare.test.ts +111 -0
  270. package/src/proxmox/provision-declare.ts +103 -0
  271. package/src/proxmox/replication-job.ts +9 -8
  272. package/src/proxmox/resource.ts +9 -9
  273. package/src/proxmox/sdn-apply-read.test.ts +16 -16
  274. package/src/proxmox/sdn-apply-read.ts +7 -7
  275. package/src/proxmox/sdn-apply.ts +3 -3
  276. package/src/proxmox/sdn-subnet-form.ts +1 -1
  277. package/src/proxmox/sdn-subnet.ts +5 -5
  278. package/src/proxmox/sdn-vnet.ts +5 -6
  279. package/src/proxmox/storage.ts +4 -3
  280. package/src/proxmox/user.ts +3 -2
  281. package/src/proxmox/values.test.ts +2 -2
  282. package/src/proxmox/values.ts +1 -1
  283. package/src/proxmox/write-only.test.ts +75 -0
  284. package/src/proxmox/write-only.ts +106 -0
  285. package/src/proxmox/zfs-pool-write.ts +1 -1
  286. package/src/proxmox/zfs-pool.ts +6 -6
  287. package/src/talos/credentials.ts +3 -3
  288. package/src/talos/values.test.ts +9 -9
  289. package/src/verify/cli.test.ts +1 -1
  290. package/src/verify/fake-engine.ts +8 -1
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `Pbs.NotificationMatcher` — which Proxmox Backup Server notifications reach which targets.
3
+ *
4
+ * ★ THIS IS WHERE A FAILED VERIFY, SYNC OR GARBAGE COLLECTION BECOMES A PAGE. pbs-verify-job.ts
5
+ * explains why verification is the only thing that notices rotten chunks; a matcher is what
6
+ * turns what it notices into a message. Route `match-severity: ['error']` to a webhook target
7
+ * (pbs-notification-target.ts, docs/pbs-notifications.md) and a failure pages someone.
8
+ *
9
+ * ⛔ A DATASTORE IN `legacy-sendmail` MODE BYPASSES EVERY MATCHER. PBS reads the datastore's
10
+ * `notification-mode` before it builds anything (src/server/notifications/mod.rs
11
+ * `lookup_datastore_notify_settings`, read at HEAD 2026-09-22): `legacy-sendmail` mails the
12
+ * `notify-user` directly and never consults a matcher. The default is `notification-system`
13
+ * today (pbs-api-types `NotificationMode`), but a datastore created before PBS 3.2 may say
14
+ * `legacy-sendmail` explicitly. `Pbs.Datastore` deliberately does not declare the mode (see
15
+ * `notify` in pbs-datastore.ts), so check it by hand before trusting a matcher with a datastore:
16
+ * `proxmox-backup-manager datastore show <name>`.
17
+ *
18
+ * ⚠️ THE EVENT `type` FOR A VERIFICATION JOB IS `verify`, NOT `verification`. PBS's own
19
+ * notifications chapter lists `verification` in its event table and `verify` in its example,
20
+ * and the source settles it: `send_verify_status` sets `("type", "verify")` (same file). A
21
+ * `match-field: ['exact:type=verification']` rule matches nothing, silently.
22
+ * Types at HEAD: `gc`, `prune`, `sync`, `verify`, `tape-backup`, `tape-load`,
23
+ * `package-updates`, `acme`, `thresholds`, `system-mail`. GC carries `datastore` and `hostname`
24
+ * but NO `job-id`; prune, sync and verify carry all three; the UI's "Test" carries no fields.
25
+ *
26
+ * ★ ADOPTING THE BUILT-IN AS IT IS. MEASURED on PBS 4.2 (2026-09-22, `proxmox-backup-manager
27
+ * notification matcher show default-matcher`): it routes everything EXCEPT successful prune
28
+ * jobs to `mail-to-root` — `invert-match` over `exact:type=prune` AND severity `info`:
29
+ * ```ts
30
+ * PbsNotificationMatcher('default-matcher', {
31
+ * target: pbs, name: 'default-matcher', targets: ['mail-to-root'],
32
+ * 'invert-match': true, 'match-field': ['exact:type=prune'], 'match-severity': ['info'],
33
+ * });
34
+ * ```
35
+ *
36
+ * ★ WHAT THIS NEEDS, READ OFF THE SERVER'S SCHEMA (generated/pbs.ts source):
37
+ * read GET Sys.Audit on /system/notifications
38
+ * write POST, PUT, DELETE Sys.Modify on /system/notifications
39
+ * ⚠️ NOT A DATASTORE PRIVILEGE. A PBS credential scoped to `/datastore/...` reads every matcher
40
+ * as absent — the "absent, then already exists" signature notification-target.ts describes.
41
+ */
42
+ import { Resource } from 'alchemy';
43
+ import * as Provider from 'alchemy/Provider';
44
+ import { type NotificationMatcherAttributes, type NotificationMatcherFields } from './notification-matcher-form.ts';
45
+ import { type PveRequirements, type WithPbsTarget } from './resource.ts';
46
+ export interface PbsNotificationMatcherProps extends NotificationMatcherFields, WithPbsTarget {
47
+ }
48
+ export interface PbsNotificationMatcher extends Resource<'Pbs.NotificationMatcher', PbsNotificationMatcherProps, NotificationMatcherAttributes, never, PveRequirements> {
49
+ }
50
+ /** ⚠️ No `retain`, for notification-matcher.ts's reason; a built-in REVERTS on delete. */
51
+ export declare const PbsNotificationMatcher: import("alchemy").ResourceClass<PbsNotificationMatcher>;
52
+ export declare const PbsNotificationMatcherProvider: () => import("effect/Layer").Layer<Provider.Provider<PbsNotificationMatcher>, never, import("effect/unstable/http/HttpClient").HttpClient>;
53
+ //# sourceMappingURL=pbs-notification-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-matcher.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAK/B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAe,MAAM,eAAe,CAAC;AAEtF,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB,EAAE,aAAa;CAAG;AAEhG,MAAM,WAAW,sBAAuB,SAAQ,QAAQ,CACtD,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,yDAA8D,CAAC;AAWlG,eAAO,MAAM,8BAA8B,4IAIxC,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * When a PBS notification target has changed, and the forms that change it.
3
+ *
4
+ * ★ THREE QUESTIONS, NOT ONE, because the three kinds of field can be checked three ways:
5
+ * plain every field the server returns in full — compared by value, like any family here
6
+ * header names from the read, values by digest (pbs-notification-target-wire.ts)
7
+ * sealed secret values and the smtp password: the server returns names at best, so values
8
+ * are checked against the seal of what this provider last wrote (write-only.ts)
9
+ * Each answers `match`, `stale` or `unknown`; only `stale` writes. `unknown` is "the plan cannot
10
+ * see it" — a variable missing from the plan's environment, or a secret this provider never
11
+ * wrote (an adoption) — and it is PRESENCE-ONLY by design: a plan never invents drift it
12
+ * cannot see, and adoption stays free.
13
+ *
14
+ * ⛔ A WRITE SENDS ONLY THE GROUPS THAT ARE STALE. Omitting `header` or `secret` from a PUT keeps
15
+ * what the server holds (api/webhook.rs `update_endpoint`), so a changed comment is written
16
+ * without reading a single secret — and a deploy environment without the secrets can still
17
+ * repair the rest. A group that IS stale needs every value it holds; a missing one fails the
18
+ * deploy by variable name before anything is sent.
19
+ */
20
+ import type { PveForm } from './client.ts';
21
+ import type { PbsNotificationTargetAttributes, PbsNotificationTargetProps } from './pbs-notification-target.ts';
22
+ import { type Environment } from './write-only.ts';
23
+ type Props = PbsNotificationTargetProps;
24
+ /**
25
+ * Why this declaration cannot be written, or nothing. Checked at PLAN, so a webhook without a
26
+ * URL fails `alchemy plan` naming the field rather than a deploy failing on a 400.
27
+ * ⚠️ "AT PLAN" MEANS `diff` FOR A TARGET WITH STATE AND THE ADOPTION PROBE (`read`) FOR ONE
28
+ * WITHOUT — pbs-notification-target-lifecycle.ts has why both are needed.
29
+ */
30
+ export declare const refusals: (props: Props) => string[];
31
+ /** Each group's values, resolved from `env`, plus the variables that were missing. */
32
+ export declare const resolveGroups: (props: Props, env?: Environment) => {
33
+ header: {
34
+ missing: readonly string[];
35
+ values: {
36
+ [x: string]: string;
37
+ };
38
+ };
39
+ sealed: {
40
+ readonly values: Readonly<Record<string, string>>;
41
+ readonly missing: readonly string[];
42
+ };
43
+ };
44
+ export type Groups = ReturnType<typeof resolveGroups>;
45
+ export type GroupState = 'match' | 'stale' | 'unknown';
46
+ /** Every field the server returns in full. `disable` is the one with no undeclared case. */
47
+ export declare const plainMatches: (live: PbsNotificationTargetAttributes, props: Props) => boolean;
48
+ export declare const headerState: (live: PbsNotificationTargetAttributes, props: Props, groups: Groups) => GroupState;
49
+ export declare const sealedState: (live: PbsNotificationTargetAttributes, props: Props, groups: Groups, sealed: string) => GroupState;
50
+ /** Which write-only groups a write carries. A create carries every declared one. */
51
+ export interface Carry {
52
+ readonly header: boolean;
53
+ readonly sealed: boolean;
54
+ }
55
+ /**
56
+ * The body of a create or an update — keys are the server's own, checked against generated/pbs.ts
57
+ * by pbs-notification-target.test.ts. ⛔ `disable` IS ALWAYS SENT, `0` included — the PVE family's
58
+ * reason: it is always compared, and "undeclared" and "false" must be one state, not a plan that
59
+ * asks for an update the PUT never performs.
60
+ */
61
+ export declare const targetForm: (props: Props, groups: Groups, carry: Carry, mode: 'create' | 'update') => PveForm;
62
+ export {};
63
+ //# sourceMappingURL=pbs-notification-target-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-target-form.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,KAAK,WAAW,EAAyC,MAAM,iBAAiB,CAAC;AAE1F,KAAK,KAAK,GAAG,0BAA0B,CAAC;AAkCxC;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,UAAW,KAAK,KAAG,MAAM,EAsB7C,CAAC;AAIF,sFAAsF;AACtF,eAAO,MAAM,aAAa,UAAW,KAAK,QAAO,WAAW;;;;;;;;;;;CAgB3D,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAKvD,4FAA4F;AAC5F,eAAO,MAAM,YAAY,SAAU,+BAA+B,SAAS,KAAK,KAAG,OAagB,CAAC;AAEpG,eAAO,MAAM,WAAW,SAChB,+BAA+B,SAC9B,KAAK,UACJ,MAAM,KACb,UAKF,CAAC;AAEF,eAAO,MAAM,WAAW,SAChB,+BAA+B,SAC9B,KAAK,UACJ,MAAM,UACN,MAAM,KACb,UAMF,CAAC;AAEF,oFAAoF;AACpF,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAmCD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,UACd,KAAK,UACJ,MAAM,SACP,KAAK,QACN,QAAQ,GAAG,QAAQ,KACxB,OAkBF,CAAC"}
@@ -0,0 +1,100 @@
1
+ import type { Input } from 'alchemy/Input';
2
+ import * as Effect from 'effect/Effect';
3
+ import type { PbsNotificationTargetAttributes, PbsNotificationTargetProps } from './pbs-notification-target.ts';
4
+ type Props = PbsNotificationTargetProps;
5
+ type Attributes = PbsNotificationTargetAttributes;
6
+ export declare const handlers: {
7
+ /** ⛔ EMPTY: `mail-to-root` is on every host, and adoption stays an explicit act (resource.ts). */
8
+ list: () => Effect.Effect<never[], never, never>;
9
+ /**
10
+ * ⛔ WITH NO `output` THIS IS ALCHEMY'S ADOPTION PROBE, AND THE ONLY PLAN-TIME HOOK A NEW TARGET
11
+ * GETS — so the refusals run here too. Measured on beta.79 (Plan.ts, the `oldState ===
12
+ * undefined` branch): a declaration with no state row is `read` with `olds: news` and never
13
+ * `diff`ed, and Apply then commits its props as `creating` BEFORE `reconcile` runs. A refusal
14
+ * left to `reconcile` fired after the props — a literal token included — were in the store.
15
+ * ⚠️ ONLY WHEN THE PROPS ARE RESOLVED: Plan skips the probe while any prop is an unresolved
16
+ * Output, and then `reconcile` is the first check. docs/pbs-notifications.md says so.
17
+ * ★ A DEFECT (`Effect.die`), NOT A FAILURE, AND THAT IS WHAT KEEPS IT FROM WEDGING A STAGE. The
18
+ * same `read`-with-no-output shape is Alchemy's RECOVERY read of an interrupted create, at plan
19
+ * and before a delete (Plan.ts, Apply.ts), with the STORED props — and both wrap it in
20
+ * `catchDefect`, degrading to "nothing recovered". A typed failure would pass that catch and
21
+ * block the plan or the delete on props the user already fixed. The cold-start probe has no
22
+ * catch, so there the defect fails the plan, as intended. A refused create sent no request,
23
+ * so "nothing recovered" is also the truth.
24
+ */
25
+ read: ({ olds, output }: {
26
+ olds: Props;
27
+ output: Attributes | undefined;
28
+ }) => Effect.Effect<{
29
+ sealed: string;
30
+ name: string;
31
+ type: import("./pbs-notification-target.ts").PbsNotificationTargetType;
32
+ origin: string;
33
+ comment: string;
34
+ disable: boolean;
35
+ mailto: string;
36
+ 'mailto-user': string;
37
+ 'from-address': string;
38
+ author: string;
39
+ server: string;
40
+ port: number;
41
+ mode: string;
42
+ username: string;
43
+ url: string;
44
+ method: string;
45
+ body: string;
46
+ header: string;
47
+ headerDigest: string;
48
+ secret: string;
49
+ } | undefined, never, import("effect/unstable/http/HttpClient").HttpClient>;
50
+ /**
51
+ * ⚠️ `Input<Props>` and `isResolved`, resource.ts's reason: at plan time a prop can still be an
52
+ * unresolved Output, and comparing a placeholder to a live value reports a phantom update.
53
+ * ⛔ A NEW `type` UNDER THE SAME `name` REPLACES DELETE-FIRST: names are unique across every
54
+ * family on the host (api `ensure_unique`), so creating the new one first would be refused.
55
+ */
56
+ diff: ({ news, olds, output, }: {
57
+ news: Input<Props>;
58
+ olds: Props;
59
+ output: Attributes | undefined;
60
+ }) => Effect.Effect<{
61
+ readonly action: 'replace';
62
+ readonly deleteFirst: boolean;
63
+ } | {
64
+ readonly deleteFirst?: never;
65
+ readonly action: 'update';
66
+ } | {
67
+ readonly deleteFirst?: never;
68
+ readonly action: 'noop';
69
+ } | undefined, never, import("effect/unstable/http/HttpClient").HttpClient>;
70
+ reconcile: ({ news, output }: {
71
+ news: Props;
72
+ output: Attributes | undefined;
73
+ }) => Effect.Effect<{
74
+ sealed: string;
75
+ name: string;
76
+ type: import("./pbs-notification-target.ts").PbsNotificationTargetType;
77
+ origin: string;
78
+ comment: string;
79
+ disable: boolean;
80
+ mailto: string;
81
+ 'mailto-user': string;
82
+ 'from-address': string;
83
+ author: string;
84
+ server: string;
85
+ port: number;
86
+ mode: string;
87
+ username: string;
88
+ url: string;
89
+ method: string;
90
+ body: string;
91
+ header: string;
92
+ headerDigest: string;
93
+ secret: string;
94
+ }, Error, import("effect/unstable/http/HttpClient").HttpClient>;
95
+ delete: ({ olds }: {
96
+ olds: Props;
97
+ }) => Effect.Effect<unknown, Error, import("effect/unstable/http/HttpClient").HttpClient>;
98
+ };
99
+ export {};
100
+ //# sourceMappingURL=pbs-notification-target-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-target-lifecycle.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target-lifecycle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AActC,KAAK,KAAK,GAAG,0BAA0B,CAAC;AACxC,KAAK,UAAU,GAAG,+BAA+B,CAAC;AA8ClD,eAAO,MAAM,QAAQ;IACnB,kGAAkG;IAClG,IAAI;IACJ;;;;;;;;;;;;;;;OAeG;IACH,IAAI,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;IAOxE;;;;;OAKG;IACH,IAAI,4BAID;QACD,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,EAAE,KAAK,CAAC;QACZ,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;KAChC;yBAIsB,SAAS;;;;yBAIa,QAAQ;;;yBAElC,MAAM;;IAGzB,SAAS,qBAAqB;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;IAyC7E,MAAM,aAAa;QAAE,IAAI,EAAE,KAAK,CAAA;KAAE;CACnC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { PbsNotificationTargetAttributes, PbsNotificationTargetProps } from './pbs-notification-target.ts';
2
+ export declare const base64: (value: string) => string;
3
+ /** ⚠️ Node's decoder skips characters it does not know rather than throwing, so this never throws. */
4
+ export declare const unbase64: (value: string) => string;
5
+ /**
6
+ * One `KeyAndBase64Val` property string — `name=<name>,value=<base64>` — split into its halves.
7
+ * ⚠️ KEYED BY NAME, NOT BY POSITION: the server serialises `name` first today, and a parser that
8
+ * relied on that would read a reordered item as a header called `value=…`.
9
+ * ★ A comma cannot occur inside either half: base64 has none, and `refusals` keeps names clean.
10
+ */
11
+ export declare const keyAndValue: (item: string) => {
12
+ name: string;
13
+ value?: string;
14
+ };
15
+ /** The wire item for one header or secret. The value is base64 — the server decodes it to use it. */
16
+ export declare const wireItem: (name: string, value: string) => string;
17
+ /** Sorted, comma-joined names — presence, the only thing the store may know about the values. */
18
+ export declare const names: (keys: readonly string[]) => string;
19
+ /**
20
+ * ★ A FIXED SALT PER TARGET, SO AN UNCHANGED HEADER SET DIGESTS THE SAME ON EVERY READ. A random
21
+ * one would rewrite the state row on every plan. The server shows these values to its auditors
22
+ * anyway; what the salt and scrypt buy is that the STORE does not become a second, weaker copy.
23
+ */
24
+ export declare const headerDigest: (target: string, pairs: Readonly<Record<string, string>>) => string;
25
+ /**
26
+ * Live JSON to attributes. `sealed` is left empty here: it is not the server's to report, and the
27
+ * handlers in pbs-notification-target.ts carry it forward from the previous state.
28
+ */
29
+ export declare const targetAttributes: (live: Record<string, unknown>, props: PbsNotificationTargetProps) => PbsNotificationTargetAttributes;
30
+ //# sourceMappingURL=pbs-notification-target-wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-target-wire.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target-wire.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AAItC,eAAO,MAAM,MAAM,UAAW,MAAM,KAAG,MAAuD,CAAC;AAE/F,sGAAsG;AACtG,eAAO,MAAM,QAAQ,UAAW,MAAM,KAAG,MAAuD,CAAC;AAEjG;;;;;GAKG;AACH,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAQxE,CAAC;AAEF,qGAAqG;AACrG,eAAO,MAAM,QAAQ,SAAU,MAAM,SAAS,MAAM,KAAG,MAChB,CAAC;AAKxC,iGAAiG;AACjG,eAAO,MAAM,KAAK,SAAU,SAAS,MAAM,EAAE,KAAG,MAIlC,CAAC;AAEf;;;;GAIG;AACH,eAAO,MAAM,YAAY,WAAY,MAAM,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,MAC3B,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,SACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SACtB,0BAA0B,KAChC,+BAkCF,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * `Pbs.NotificationTarget` — where a Proxmox Backup Server sends a notification: a `webhook`, or
3
+ * mail through `sendmail` or `smtp`.
4
+ *
5
+ * ★ THE WEBHOOK IS THE POINT. A failed verify, sync or garbage collection reaches a human through a
6
+ * target a matcher names (pbs-notification-matcher.ts). Out of the box that is `mail-to-root`,
7
+ * one mailbox on one host; a webhook can post an Alertmanager alert instead, and then the failure
8
+ * pages like everything else. docs/pbs-alertmanager-body.md has the body template.
9
+ *
10
+ * ⛔ SECRETS ARE DECLARED BY THE NAME OF AN ENVIRONMENT VARIABLE, NEVER BY VALUE, and NO VALUE EVER
11
+ * REACHES STATE — not as a prop, not as an attribute. write-only.ts has the whole argument; the
12
+ * short form: Alchemy stores props and attributes unencrypted, so `secret`, `password` and any
13
+ * header holding a credential take `{ fromEnv: 'NAME' }`, read by the deploying process at call
14
+ * time. What the store keeps is presence (names) and digests, and the plan diffs on those.
15
+ * ★ THIS IS WHERE THE PBS FAMILY PARTS FROM notification-target.ts (PVE), which refuses every
16
+ * secret and so cannot create a signed webhook at all.
17
+ *
18
+ * ⛔ THE PER-OBJECT PATH CARRIES THE FAMILY: `config/notifications/endpoints/{type}/{name}`. `type`
19
+ * is identity, and changing it or `name` plans a REPLACE here — `diff` compares them with the
20
+ * recorded props. `/config/notifications/targets` is a read-only union view, as on PVE.
21
+ *
22
+ * ⚠️ A BUILT-IN TARGET REVERTS ON DELETE instead of disappearing (`origin: builtin`, measured on
23
+ * PBS 4.2 for `mail-to-root`), and PBS reports success either way — notification-target.ts has
24
+ * the consequence. Read `origin` before declaring a name you did not create.
25
+ *
26
+ * ★ WHAT THIS NEEDS (generated/pbs.ts source): Sys.Audit on /system/notifications to read,
27
+ * Sys.Modify there to write. A datastore-scoped credential reads every target as absent.
28
+ */
29
+ import { Resource } from 'alchemy';
30
+ import * as Provider from 'alchemy/Provider';
31
+ import type { PveRequirements, WithPbsTarget } from './resource.ts';
32
+ import type { FromEnv } from './write-only.ts';
33
+ export type PbsNotificationTargetType = 'sendmail' | 'smtp' | 'webhook';
34
+ /**
35
+ * ⚠️ PBS'S OWN KEY NAMES, DASHES INCLUDED, for the reason backup-job.ts gives. A field outside its
36
+ * family (a `url` on a sendmail target) is refused at plan by name, not sent for a 400.
37
+ * ⚠️ AN UNDECLARED FIELD IS NEITHER SENT NOR COMPARED; `''` or `[]` (or `{}`) CLEARS ONE.
38
+ */
39
+ export interface PbsNotificationTargetProps extends WithPbsTarget {
40
+ /** ⛔ IDENTITY: it picks the family and the URL. Changing it is a replace. */
41
+ type: PbsNotificationTargetType;
42
+ /** Unique across ALL families on the host: a webhook cannot be called `mail-to-root`. */
43
+ name: string;
44
+ comment?: string;
45
+ /** Configured but not delivering. Always sent and always compared. */
46
+ disable?: boolean;
47
+ /** sendmail, smtp: recipient addresses. Order is not meaning. */
48
+ mailto?: readonly string[];
49
+ /** sendmail, smtp: PBS users whose configured address receives the mail. */
50
+ 'mailto-user'?: readonly string[];
51
+ /** smtp: required. sendmail: optional. */
52
+ 'from-address'?: string;
53
+ author?: string;
54
+ /** smtp: the relay host. Required. */
55
+ server?: string;
56
+ /** smtp. Unset lets PBS pick from `mode`. */
57
+ port?: number;
58
+ /** smtp. PBS's default is `tls`. */
59
+ mode?: 'insecure' | 'starttls' | 'tls';
60
+ /** smtp. */
61
+ username?: string;
62
+ /** smtp: ⛔ WRITE-ONLY. The server never returns it; the plan compares its seal. */
63
+ password?: FromEnv;
64
+ /** webhook: required. Supports templating: `{{ secrets.<name> }}` keeps a token out of it. */
65
+ url?: string;
66
+ /** webhook: required. */
67
+ method?: 'get' | 'post' | 'put';
68
+ /**
69
+ * webhook: header name → template text, or `{ fromEnv }` for a value that is itself a secret.
70
+ * ⚠️ PLAIN VALUES ARE PROPS, AND PROPS ARE STORED: `Content-Type` is fine, a token is not. Put a
71
+ * credential in `secret` and write `'Bearer {{ secrets.token }}'` here instead.
72
+ */
73
+ header?: Readonly<Record<string, FromEnv | string>>;
74
+ /**
75
+ * webhook: the body TEMPLATE, as text. ★ Declared DECODED — the wire is base64, and this family
76
+ * encodes on write and decodes on read, so a plan shows a readable diff.
77
+ */
78
+ body?: string;
79
+ /** webhook: ⛔ WRITE-ONLY. Name → variable. Referenced as `{{ secrets.<name> }}`. */
80
+ secret?: Readonly<Record<string, FromEnv>>;
81
+ }
82
+ /** ⛔ NO VALUE OF A SECRET, PASSWORD OR HEADER — names and digests only. */
83
+ export interface PbsNotificationTargetAttributes {
84
+ name: string;
85
+ type: PbsNotificationTargetType;
86
+ /** `builtin`, `modified-builtin`, `user-created` — reported, never compared. */
87
+ origin: string;
88
+ comment: string;
89
+ disable: boolean;
90
+ mailto: string;
91
+ 'mailto-user': string;
92
+ 'from-address': string;
93
+ author: string;
94
+ server: string;
95
+ /** 0 means PBS holds no port. */
96
+ port: number;
97
+ mode: string;
98
+ username: string;
99
+ url: string;
100
+ method: string;
101
+ /** The decoded body template. */
102
+ body: string;
103
+ /** Header NAMES, sorted — presence. */
104
+ header: string;
105
+ /** scrypt digest of the live header pairs, fixed salt per target. */
106
+ headerDigest: string;
107
+ /** Secret NAMES, sorted — all PBS will say. */
108
+ secret: string;
109
+ /**
110
+ * Seal of the secret values and password THIS PROVIDER LAST WROTE; `''` if it never wrote them
111
+ * (an adoption). ⚠️ `''` makes those values presence-only until the first write that carries them.
112
+ */
113
+ sealed: string;
114
+ }
115
+ export interface PbsNotificationTarget extends Resource<'Pbs.NotificationTarget', PbsNotificationTargetProps, PbsNotificationTargetAttributes, never, PveRequirements> {
116
+ }
117
+ export declare const PbsNotificationTarget: import("alchemy").ResourceClass<PbsNotificationTarget>;
118
+ /**
119
+ * ⛔ `Provider.of` STAYS HERE, for resource.ts's reason: it is the one place the handlers are
120
+ * checked against the concrete resource types, so the lifecycle file cannot drift from them.
121
+ */
122
+ export declare const PbsNotificationTargetProvider: () => import("effect/Layer").Layer<Provider.Provider<PbsNotificationTarget>, never, import("effect/unstable/http/HttpClient").HttpClient>;
123
+ //# sourceMappingURL=pbs-notification-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pbs-notification-target.d.ts","sourceRoot":"","sources":["../../src/proxmox/pbs-notification-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,MAAM,yBAAyB,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAExE;;;;GAIG;AACH,MAAM,WAAW,0BAA2B,SAAQ,aAAa;IAC/D,6EAA6E;IAC7E,IAAI,EAAE,yBAAyB,CAAC;IAChC,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,KAAK,CAAC;IACvC,YAAY;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8FAA8F;IAC9F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;IACpD;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC5C;AAED,2EAA2E;AAC3E,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,yBAAyB,CAAC;IAChC,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAsB,SAAQ,QAAQ,CACrD,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,KAAK,EACL,eAAe,CAChB;CAAG;AAEJ,eAAO,MAAM,qBAAqB,wDAA4D,CAAC;AAE/F;;;GAGG;AACH,eAAO,MAAM,6BAA6B,2IAIvC,CAAC"}
@@ -37,10 +37,10 @@
37
37
  * answers 401 "authentication failure", which reads as a bad credential rather than as a
38
38
  * malformed header — the same trap credentials.ts already records for PVE's colon form.
39
39
  * ⛔ AND THERE IS NO MOUNT TO MINT FROM. `mint()` runs `bao read <mount>/creds/<role>`; no
40
- * OpenBao mount vends PBS tokens — `proxmox-tb4` and `proxmox-ops` vend PVE ones. The
40
+ * OpenBao mount vends PBS tokens — `proxmox-c1` and `proxmox-c2` vend PVE ones. The
41
41
  * `kv/infra/proxmox` shelf holds a READ-ONLY `Audit` token for PBS, and a read-only token
42
42
  * cannot create a prune job. I could not confirm that shelf's contents: this machine's
43
- * claude-code approle answers 403 on `sys/mounts` AND on `kv/metadata/infra/proxmox`
43
+ * agent approle answers 403 on `sys/mounts` AND on `kv/metadata/infra/proxmox`
44
44
  * (MEASURED). What is needed is a dynamic PBS mount vending a `provision` role with
45
45
  * `Datastore.Modify` — say that, rather than reaching for the stored auditor token.
46
46
  *
@@ -12,14 +12,14 @@
12
12
  *
13
13
  * ⛔ THE CREDENTIAL IS A PBS TOKEN AND IT DOES NOT EXIST YET; NO MOUNT NAME IS INVENTED IN THIS
14
14
  * FILE. PBS wants `user@realm!tokenname` plus a UUID secret, issued by PBS — a PVE token is not
15
- * one, whatever it is spelled like. MEASURED from this machine on 2026-09-13: the `claude-code`
15
+ * one, whatever it is spelled like. MEASURED from this machine on 2026-09-13: the agent's
16
16
  * approle cannot enumerate mounts (`bao secrets list` -> 403) and
17
17
  * `bao token capabilities kv/infra/proxmox/pbs` -> `deny`, so I could not confirm from here what
18
18
  * does or does not exist. What credentials.ts records is that every PBS token on the kv shelf is
19
- * READ-ONLY (`Audit`, as `monitoring@pve`) and STATIC — too narrow to create a sync job, and
19
+ * READ-ONLY (`Audit`, as `metrics@pve`) and STATIC — too narrow to create a sync job, and
20
20
  * exactly the kind of credential this provider exists to avoid writing with.
21
21
  * ★ SO THE MOUNT IS A `PbsTarget.mount` THE STACK SUPPLIES, and somebody has to build it first:
22
- * a dynamic PBS mount with `read` and `provision` roles mirroring `proxmox-tb4`. Until it
22
+ * a dynamic PBS mount with `read` and `provision` roles mirroring `proxmox-c1`. Until it
23
23
  * exists this family can be declared and cannot be deployed. `permission denied` means the
24
24
  * grant is missing — say which mount and role you needed; do not fall back to the shelf token.
25
25
  *
@@ -80,7 +80,7 @@ export interface SyncJobProps extends WithPbsTarget {
80
80
  * `Pbs.Remote` family is OUT OF SCOPE for this package rather than merely unwritten:
81
81
  * `POST /config/remote` requires `password`, and Alchemy persists props and attributes to its
82
82
  * state store UNENCRYPTED (StateEncoding.ts tags Redacted values rather than encrypting them),
83
- * which here is the `alchemy` Postgres that pg-backup.sh dumps nightly to CT100. A remote's
83
+ * which here is the `alchemy` Postgres that a nightly job dumps to a backup guest. A remote's
84
84
  * password in a prop is that password in four places, for months. The only Remote resource that
85
85
  * could exist would refuse `password` the way storage.ts refuses it — as a `never` — and could
86
86
  * therefore never CREATE a remote, which is a resource that cannot do what its name promises.
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * ⛔ THIS FILE CANNOT AUTHENTICATE UNTIL TWO THINGS OUTSIDE IT CHANGE, AND IT IS SHIPPED SAYING SO
13
13
  * RATHER THAN SHIPPED LOOKING FINISHED. Both are recorded on `PbsTarget` below:
14
- * 1. `credentials.ts` has no PBS mint. MEASURED 2026-09-13 from this Mac: the `claude-code`
14
+ * 1. `credentials.ts` has no PBS mint. MEASURED 2026-09-13 from this Mac: the agent's
15
15
  * approle is refused `sys/mounts`, `kv/infra/proxmox` and `proxmox-pbs/creds/read` alike —
16
16
  * 403 permission denied on all three — so there is no mount to name and none is invented.
17
17
  * 2. `client.ts`'s `authorization()` builds a PVE header, and PBS will not accept it. See the
@@ -8,11 +8,11 @@
8
8
  * its own state would have reported noop straight past a hand-edit in the UI.
9
9
  *
10
10
  * ⚠️ IT 403'd UNTIL THE ROLE WAS WIDENED, AND THE HISTORY IS WORTH KEEPING. `hf-provision@pve`
11
- * held `LXCProvisioner` on `/` with no `Pool.Allocate`, so reconcile answered
12
- * "Permission check failed (/pool/house, Pool.Allocate)". The credential could not widen itself
11
+ * held the provision role on `/` with no `Pool.Allocate`, so reconcile answered
12
+ * "Permission check failed (/pool/lab, Pool.Allocate)". The credential could not widen itself
13
13
  * — `PUT /access/roles` is 403 for it too — so the role was extended over SSH with
14
- * `pveum role modify LXCProvisioner --privs "<existing>,Pool.Allocate,Pool.Audit"`, preserving
15
- * every existing privilege. Each new resource in this package should state the privileges its
14
+ * `pveum role modify <role> --privs "<existing>,Pool.Allocate,Pool.Audit"`, preserving every
15
+ * existing privilege. `PROVISION_PRIVILEGES` (provision-baseline.ts) carries both now. Each new resource in this package should state the privileges its
16
16
  * reconcile needs, so widening stays a deliberate act rather than a reaction to a 403.
17
17
  */
18
18
  import { Resource } from 'alchemy';
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The provisioning baseline: the access every PVE cluster and node needs before a stack built on
3
+ * this package can manage it — one role, the users OpenBao mints tokens for, the group that fences
4
+ * the mint, and the grants that bind them. ONE description, read by both halves:
5
+ * · provision-declare.ts turns it into `Proxmox.Role`/`Group`/`User`/`Acl` resources, so a stack
6
+ * adopts the baseline and keeps it (drift is a plan, not a 403 weeks later);
7
+ * · provision-bootstrap.ts turns it into the one-time root commands for a NEW cluster or node.
8
+ * The two cannot drift apart because neither holds a name or a privilege of its own.
9
+ *
10
+ * ⛔ THE PROVISION LANE CANNOT CREATE ITSELF. Every write here runs as a token OpenBao mints for the
11
+ * provision user, and minting needs that user to exist, in the mint group, bound to this role.
12
+ * So a new cluster is bootstrapped ONCE by root@pam with the generated commands, and the stack
13
+ * then adopts what they made (docs/provision-baseline.md).
14
+ *
15
+ * ★ ONE PRIVILEGE LIST FOR EVERY FAMILY, NOT A ROLE PER RESOURCE. The list is what the families'
16
+ * reconciles need, unioned — the set a hand-kept provision role reached one 403 at a time, each
17
+ * step recorded where it was hit (pool.ts, sdn-vnet.ts, ha-rule.ts). It includes what the lane needs
18
+ * to manage THIS baseline (`Sys.Modify` for the role, `Realm.AllocateUser`/`User.Modify` for the
19
+ * users, `Group.Allocate`, `Permissions.Modify` for the grants), so declaring it can never narrow
20
+ * the lane out of its own repair (role.ts: "A ROLE CAN LOCK ITS OWN PROVIDER OUT").
21
+ * ⚠️ NOT EVERY FAMILY: root@pam-only writes (device passthrough, bind mounts — lxc-judge.ts) and
22
+ * privileges a family names as still missing (`VM.Replicate`, replication-job.ts) are outside it.
23
+ */
24
+ /** The provision role's privileges, sorted — the exact set, never an addition to a live one. */
25
+ export declare const PROVISION_PRIVILEGES: readonly string[];
26
+ /** The names a baseline uses. Every field has a generic default (`PROVISION_DEFAULTS`). */
27
+ export interface ProvisionNames {
28
+ /** The role holding `PROVISION_PRIVILEGES` on `/`. */
29
+ readonly role?: string | undefined;
30
+ /** The user OpenBao's `provision` role mints tokens for, realm-qualified. */
31
+ readonly provisionUser?: string | undefined;
32
+ /** The group whose members OpenBao may mint for — the fence around the mint. */
33
+ readonly mintGroup?: string | undefined;
34
+ /** The user OpenBao's `read` role mints for, or `null` for a baseline with no read lane. */
35
+ readonly readUser?: string | null | undefined;
36
+ /** The role the read user holds on `/`. ⛔ It must already exist: a built-in, or one you declare. */
37
+ readonly readRole?: string | undefined;
38
+ /** The comment on the group and both users — how a person on the node learns what they are. */
39
+ readonly comment?: string | undefined;
40
+ }
41
+ /** Every name, resolved: what `PROVISION_DEFAULTS` holds and what a baseline is built from. */
42
+ export type ResolvedProvisionNames = {
43
+ readonly [K in keyof ProvisionNames]-?: Exclude<ProvisionNames[K], undefined>;
44
+ };
45
+ /** ★ Generic, kit-prefixed names: nothing here is any one estate's. */
46
+ export declare const PROVISION_DEFAULTS: ResolvedProvisionNames;
47
+ /** Which credential lane a user or a grant belongs to — the OpenBao role that mints for it. */
48
+ export type ProvisionLane = 'provision' | 'read';
49
+ /** A baseline, resolved: exactly what the declaration holds and the bootstrap makes. */
50
+ export interface ProvisionBaseline {
51
+ readonly role: {
52
+ readonly roleid: string;
53
+ readonly privs: readonly string[];
54
+ };
55
+ readonly group: {
56
+ readonly groupid: string;
57
+ readonly comment: string;
58
+ };
59
+ readonly users: readonly {
60
+ readonly lane: ProvisionLane;
61
+ readonly userid: string;
62
+ readonly comment: string;
63
+ readonly groups: readonly string[];
64
+ }[];
65
+ /** Each binds one user to one role on `/`, with propagate — the only shape the lanes need. */
66
+ readonly grants: readonly {
67
+ readonly lane: ProvisionLane;
68
+ readonly userid: string;
69
+ readonly roleid: string;
70
+ }[];
71
+ }
72
+ /** Resolve `names` over the defaults and check them. Throws with every problem at once. */
73
+ export declare const provisionBaseline: (names?: ProvisionNames) => ProvisionBaseline;
74
+ //# sourceMappingURL=provision-baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision-baseline.d.ts","sourceRoot":"","sources":["../../src/proxmox/provision-baseline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,gGAAgG;AAChG,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EA4BhD,CAAC;AAEH,2FAA2F;AAC3F,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,gFAAgF;IAChF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,oGAAoG;IACpG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,+FAA+F;AAC/F,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,EAAE,CAAC,IAAI,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;CAC9E,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,EAAE,sBAQ/B,CAAC;AAEH,+FAA+F;AAC/F,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,MAAM,CAAC;AAEjD,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAC9E,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,QAAQ,CAAC,KAAK,EAAE,SAAS;QACvB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;KACpC,EAAE,CAAC;IACJ,8FAA8F;IAC9F,QAAQ,CAAC,MAAM,EAAE,SAAS;QACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,EAAE,CAAC;CACL;AA8BD,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB,WAAW,cAAc,KAAQ,iBAwB9D,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * `provisionBootstrap` — the provisioning baseline (provision-baseline.ts) as the one-time root
3
+ * commands for a NEW cluster or node: a POSIX `sh` script, printed, never run from here.
4
+ *
5
+ * bun -e "import { provisionBootstrap } from '@homeflare/alchemy/proxmox';
6
+ * process.stdout.write(provisionBootstrap())" | ssh root@<node> sh
7
+ *
8
+ * ⛔ WHY IT EXISTS: THE PROVISION LANE CANNOT CREATE ITSELF. Every resource in this package runs as a
9
+ * token OpenBao mints for the provision user, and a cluster without that user, its group and its
10
+ * grant has nothing to mint for — the plan that would create them cannot authenticate. So root
11
+ * makes them once, and the stack adopts and keeps them (provision-declare.ts). This is the only
12
+ * hand step, and it is generated from the same baseline the stack declares.
13
+ * ⛔ NEVER A TOKEN, NEVER A PASSWORD. The users are created with neither: OpenBao mints short-lived
14
+ * tokens for them later, and an `@pve` user with no password cannot log in to the UI. Nothing
15
+ * secret is in the script, so it can be read, reviewed and pasted.
16
+ * ★ CHECK, THEN CHANGE — IDEMPOTENT BY CONSTRUCTION. Each object is read first (`pvesh get … json`,
17
+ * parsed with Perl's core JSON::PP, which every PVE node has), compared with the baseline, and
18
+ * written only when it differs, naming what it does. A second run prints `ok` for everything and
19
+ * writes nothing. It also CONVERGES: a role with other privileges is set to exactly the baseline,
20
+ * as the stack's `Proxmox.Role` would set it (role.ts: a declaration replaces the set).
21
+ * ★ ONE NODE PER CLUSTER. Users, groups, roles and ACLs live in `/etc/pve/user.cfg`, which pmxcfs
22
+ * shares across the cluster: a node joining a cluster that has the baseline needs nothing, and a
23
+ * run there is all `ok`. A new standalone node or a new cluster is where it creates.
24
+ * ⚠️ NAMES ARE NOT QUOTED INTO SAFETY, THEY ARE REFUSED INTO IT: provision-baseline.ts admits only
25
+ * characters that need no quoting in `sh` or in a Perl `q{}`.
26
+ */
27
+ import { type ProvisionNames } from './provision-baseline.ts';
28
+ /**
29
+ * The script for `names` (defaults: `PROVISION_DEFAULTS`). Pure: it reads nothing and runs nothing.
30
+ * Throws, like `provisionBaseline`, on a name the baseline refuses.
31
+ */
32
+ export declare const provisionBootstrap: (names?: ProvisionNames) => string;
33
+ //# sourceMappingURL=provision-bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision-bootstrap.d.ts","sourceRoot":"","sources":["../../src/proxmox/provision-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,yBAAyB,CAAC;AAsFjC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,WAAW,cAAc,KAAQ,MAc/D,CAAC"}
@@ -0,0 +1,38 @@
1
+ export type CliUser = {
2
+ comment: string;
3
+ email: string;
4
+ enable: number;
5
+ expire: number;
6
+ firstname: string;
7
+ lastname: string;
8
+ groups: string[];
9
+ };
10
+ export type CliGrant = {
11
+ path: string;
12
+ type: string;
13
+ ugid: string;
14
+ roleid: string;
15
+ propagate: number;
16
+ };
17
+ export type CliState = {
18
+ roles: Record<string, string[]>;
19
+ groups: Record<string, {
20
+ comment: string;
21
+ }>;
22
+ users: Record<string, CliUser>;
23
+ acl: CliGrant[];
24
+ };
25
+ /** A cluster as PVE installs it: the built-in auditor role, and nothing of the baseline. */
26
+ export declare const freshCluster: () => CliState;
27
+ /** Every item GET the scripts and the providers make, keyed `access/…` without a leading slash. */
28
+ export declare const apiView: (state: CliState) => Record<string, unknown>;
29
+ export type ScriptRun = {
30
+ code: number;
31
+ stdout: string;
32
+ stderr: string;
33
+ writes: string[];
34
+ state: CliState;
35
+ };
36
+ /** Run `script` under `sh` against `state`, with the fakes first on PATH. */
37
+ export declare const runScript: (script: string, state: CliState) => Promise<ScriptRun>;
38
+ //# sourceMappingURL=provision-cli-fake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision-cli-fake.d.ts","sourceRoot":"","sources":["../../src/proxmox/provision-cli-fake.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,EAAE,QAAQ,EAAE,CAAC;CACjB,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,YAAY,QAAO,QAc9B,CAAC;AAIH,mGAAmG;AACnG,eAAO,MAAM,OAAO,UAAW,QAAQ,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAsB/D,CAAC;AA0FF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;CACjB,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,SAAS,WAAkB,MAAM,SAAS,QAAQ,KAAG,OAAO,CAAC,SAAS,CAkClF,CAAC"}