@reddoorla/maintenance 0.68.0 → 0.69.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 (38) hide show
  1. package/dist/{chunk-H6YZBXBQ.js → chunk-2DCA7FHZ.js} +4 -4
  2. package/dist/{chunk-LCKKIJ22.js → chunk-42KKVLYN.js} +3 -3
  3. package/dist/{chunk-WCN54744.js → chunk-6G7BC5SN.js} +4 -4
  4. package/dist/{chunk-2E2X5BCG.js → chunk-AESJBEM7.js} +2 -2
  5. package/dist/{chunk-MAYHLXCS.js → chunk-E2GKKUEX.js} +2 -2
  6. package/dist/{chunk-XVR7UM6Z.js → chunk-JNXCDUYB.js} +4 -4
  7. package/dist/cli/bin.js +7 -7
  8. package/dist/cli/commands/audit.js +3 -3
  9. package/dist/client/index.d.ts +84 -0
  10. package/dist/client/index.js +47 -0
  11. package/dist/client/index.js.map +1 -0
  12. package/dist/{digest-J7TDG62Q.js → digest-Q2TAQHXF.js} +7 -7
  13. package/dist/{github-signals-PP7GWYIY.js → github-signals-CLQC2IPY.js} +4 -4
  14. package/dist/index.js +11 -11
  15. package/dist/{init-WLR35YGN.js → init-UA6D7GKW.js} +6 -6
  16. package/dist/{launch-2HPQXWII.js → launch-AENAS2O2.js} +6 -6
  17. package/dist/{orchestrate-PVCGBH4K.js → orchestrate-GADNFGDH.js} +3 -3
  18. package/dist/{preflight-KWVYJ2DU.js → preflight-D5RQGX4V.js} +4 -4
  19. package/dist/recipes/sync-configs.js +2 -2
  20. package/dist/{report-ZBFMTT76.js → report-3FJ224H5.js} +3 -3
  21. package/dist/{selftest-LFZPZRJP.js → selftest-55OJIWEB.js} +5 -5
  22. package/dist/{sync-configs-6GBZLGRQ.js → sync-configs-TIBO6DUJ.js} +3 -3
  23. package/package.json +5 -1
  24. /package/dist/{chunk-H6YZBXBQ.js.map → chunk-2DCA7FHZ.js.map} +0 -0
  25. /package/dist/{chunk-LCKKIJ22.js.map → chunk-42KKVLYN.js.map} +0 -0
  26. /package/dist/{chunk-WCN54744.js.map → chunk-6G7BC5SN.js.map} +0 -0
  27. /package/dist/{chunk-2E2X5BCG.js.map → chunk-AESJBEM7.js.map} +0 -0
  28. /package/dist/{chunk-MAYHLXCS.js.map → chunk-E2GKKUEX.js.map} +0 -0
  29. /package/dist/{chunk-XVR7UM6Z.js.map → chunk-JNXCDUYB.js.map} +0 -0
  30. /package/dist/{digest-J7TDG62Q.js.map → digest-Q2TAQHXF.js.map} +0 -0
  31. /package/dist/{github-signals-PP7GWYIY.js.map → github-signals-CLQC2IPY.js.map} +0 -0
  32. /package/dist/{init-WLR35YGN.js.map → init-UA6D7GKW.js.map} +0 -0
  33. /package/dist/{launch-2HPQXWII.js.map → launch-AENAS2O2.js.map} +0 -0
  34. /package/dist/{orchestrate-PVCGBH4K.js.map → orchestrate-GADNFGDH.js.map} +0 -0
  35. /package/dist/{preflight-KWVYJ2DU.js.map → preflight-D5RQGX4V.js.map} +0 -0
  36. /package/dist/{report-ZBFMTT76.js.map → report-3FJ224H5.js.map} +0 -0
  37. /package/dist/{selftest-LFZPZRJP.js.map → selftest-55OJIWEB.js.map} +0 -0
  38. /package/dist/{sync-configs-6GBZLGRQ.js.map → sync-configs-TIBO6DUJ.js.map} +0 -0
@@ -12,6 +12,9 @@ import {
12
12
  resolveCopy,
13
13
  stampSent
14
14
  } from "./chunk-6JFOAPW4.js";
15
+ import {
16
+ defaultResendClient
17
+ } from "./chunk-WEKL2HYJ.js";
15
18
  import {
16
19
  recordFleetEventsBestEffort
17
20
  } from "./chunk-OTBA7DON.js";
@@ -24,9 +27,6 @@ import {
24
27
  openBase,
25
28
  readAirtableConfig
26
29
  } from "./chunk-HN6I2XWI.js";
27
- import {
28
- defaultResendClient
29
- } from "./chunk-WEKL2HYJ.js";
30
30
 
31
31
  // src/reports/send/render-email.ts
32
32
  function toInlineAttachment(a) {
@@ -309,4 +309,4 @@ export {
309
309
  parseAddresses,
310
310
  isProbablyEmail
311
311
  };
312
- //# sourceMappingURL=chunk-H6YZBXBQ.js.map
312
+ //# sourceMappingURL=chunk-2DCA7FHZ.js.map
@@ -9,13 +9,13 @@ import {
9
9
  } from "./chunk-ZYBOT5PM.js";
10
10
  import {
11
11
  syncConfigs
12
- } from "./chunk-XVR7UM6Z.js";
12
+ } from "./chunk-JNXCDUYB.js";
13
13
  import {
14
14
  withRecipe
15
15
  } from "./chunk-XKOZUVK2.js";
16
16
  import {
17
17
  runAudits
18
- } from "./chunk-WCN54744.js";
18
+ } from "./chunk-6G7BC5SN.js";
19
19
  import {
20
20
  siteLabel
21
21
  } from "./chunk-XXTZBPUY.js";
@@ -135,4 +135,4 @@ export {
135
135
  DEFAULT_INIT_STEPS,
136
136
  init
137
137
  };
138
- //# sourceMappingURL=chunk-LCKKIJ22.js.map
138
+ //# sourceMappingURL=chunk-42KKVLYN.js.map
@@ -1,12 +1,12 @@
1
- import {
2
- baselineVersions
3
- } from "./chunk-LKGVSM2O.js";
4
1
  import {
5
2
  readGitHubConfig
6
3
  } from "./chunk-GASBX52O.js";
7
4
  import {
8
5
  assertUrlSegment
9
6
  } from "./chunk-YEGHUODU.js";
7
+ import {
8
+ baselineVersions
9
+ } from "./chunk-LKGVSM2O.js";
10
10
  import {
11
11
  defaultSpawn
12
12
  } from "./chunk-HVOOCK6L.js";
@@ -1510,4 +1510,4 @@ export {
1510
1510
  runAudits,
1511
1511
  runAuditsAcross
1512
1512
  };
1513
- //# sourceMappingURL=chunk-WCN54744.js.map
1513
+ //# sourceMappingURL=chunk-6G7BC5SN.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  approveBlockers
3
- } from "./chunk-MAYHLXCS.js";
3
+ } from "./chunk-E2GKKUEX.js";
4
4
  import {
5
5
  siteSlug
6
6
  } from "./chunk-C3PDS623.js";
@@ -248,4 +248,4 @@ export {
248
248
  readDigestState,
249
249
  writeDigestState
250
250
  };
251
- //# sourceMappingURL=chunk-2E2X5BCG.js.map
251
+ //# sourceMappingURL=chunk-AESJBEM7.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  isProbablyEmail,
7
7
  parseAddresses
8
- } from "./chunk-H6YZBXBQ.js";
8
+ } from "./chunk-2DCA7FHZ.js";
9
9
  import {
10
10
  listAllReports
11
11
  } from "./chunk-6JFOAPW4.js";
@@ -319,4 +319,4 @@ export {
319
319
  preflight,
320
320
  approveBlockers
321
321
  };
322
- //# sourceMappingURL=chunk-MAYHLXCS.js.map
322
+ //# sourceMappingURL=chunk-E2GKKUEX.js.map
@@ -1,10 +1,10 @@
1
- import {
2
- withRecipe
3
- } from "./chunk-XKOZUVK2.js";
4
1
  import {
5
2
  ALL_TEMPLATES,
6
3
  templatesByName
7
4
  } from "./chunk-CASCWQQX.js";
5
+ import {
6
+ withRecipe
7
+ } from "./chunk-XKOZUVK2.js";
8
8
  import {
9
9
  listTrackedFiles,
10
10
  removeFromIndex
@@ -208,4 +208,4 @@ export {
208
208
  isConfigName,
209
209
  syncConfigs
210
210
  };
211
- //# sourceMappingURL=chunk-XVR7UM6Z.js.map
211
+ //# sourceMappingURL=chunk-JNXCDUYB.js.map
package/dist/cli/bin.js CHANGED
@@ -105,7 +105,7 @@ cli.command("sync-configs [site]", "Sync canonical configs into a site.").option
105
105
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
106
106
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
107
107
  async (site, opts) => runOrExit(
108
- async () => (await import("../sync-configs-6GBZLGRQ.js")).runSyncConfigsCommand(site, opts),
108
+ async () => (await import("../sync-configs-TIBO6DUJ.js")).runSyncConfigsCommand(site, opts),
109
109
  opts
110
110
  )
111
111
  );
@@ -176,14 +176,14 @@ cli.command(
176
176
  "--fleet <inventory>",
177
177
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
178
178
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
179
- async (site, opts) => runOrExit(async () => (await import("../init-WLR35YGN.js")).runInitCommand(site, opts), opts)
179
+ async (site, opts) => runOrExit(async () => (await import("../init-UA6D7GKW.js")).runInitCommand(site, opts), opts)
180
180
  );
181
181
  cli.command(
182
182
  "launch <site>",
183
183
  "Bootstrap + first-audit a site, then draft its launch email for approval."
184
184
  ).action(
185
185
  async (site, opts) => runOrExit(
186
- async () => (await import("../launch-2HPQXWII.js")).runLaunchCommand(site, opts),
186
+ async () => (await import("../launch-AENAS2O2.js")).runLaunchCommand(site, opts),
187
187
  opts
188
188
  )
189
189
  );
@@ -201,7 +201,7 @@ cli.command(
201
201
  "Operator self-tests. kind=email: preview a report email for a site (or --all) to yourself."
202
202
  ).option("--type <type>", "Report type: announcement (default) | maintenance | testing | launch").option("--to <addr>", "Recipient(s), comma-separated. Default: OPERATOR_EMAIL.").option("--all", "Send a preview for every maintenance site (to --to/operator).").option("--dry-run", "Render only; write reports/<slug>/selftest-<type>.html; do not send.").action(
203
203
  async (kind, site, opts) => runOrExit(
204
- async () => (await import("../selftest-LFZPZRJP.js")).runSelftestCommand(kind, site, opts),
204
+ async () => (await import("../selftest-55OJIWEB.js")).runSelftestCommand(kind, site, opts),
205
205
  opts
206
206
  )
207
207
  );
@@ -213,7 +213,7 @@ cli.command(
213
213
  "Fleet mode: announcement\u2192maintenance sites; maintenance/testing\u2192all schedulable sites."
214
214
  ).action(
215
215
  async (site, opts) => runOrExit(
216
- async () => (await import("../preflight-KWVYJ2DU.js")).runPreflightCommand(site, opts),
216
+ async () => (await import("../preflight-D5RQGX4V.js")).runPreflightCommand(site, opts),
217
217
  opts
218
218
  )
219
219
  );
@@ -234,7 +234,7 @@ cli.command("report [site]", "Draft or send maintenance/testing reports.").optio
234
234
  "Email the operator one daily digest of reports ready for approval (skips when empty)."
235
235
  ).action(
236
236
  async (site, opts) => runOrExit(
237
- async () => (await import("../report-ZBFMTT76.js")).runReportCommand(site, opts),
237
+ async () => (await import("../report-3FJ224H5.js")).runReportCommand(site, opts),
238
238
  opts
239
239
  )
240
240
  );
@@ -243,7 +243,7 @@ cli.command(
243
243
  "Sweep the fleet for GitHub signals (Renovate-failing/CI/last-commit) and write Airtable."
244
244
  ).option("--fleet", "Run across every site in the Airtable inventory.").option("--write-airtable", "Write each site's signals back to its Websites row.").action(
245
245
  async (opts) => runOrExit(
246
- async () => (await import("../github-signals-PP7GWYIY.js")).runGitHubSignalsCommand({
246
+ async () => (await import("../github-signals-CLQC2IPY.js")).runGitHubSignalsCommand({
247
247
  fleet: opts.fleet,
248
248
  writeAirtable: opts.writeAirtable
249
249
  }),
@@ -12,15 +12,15 @@ import {
12
12
  import {
13
13
  ALL_AUDIT_NAMES,
14
14
  runOneAudit
15
- } from "../../chunk-WCN54744.js";
15
+ } from "../../chunk-6G7BC5SN.js";
16
+ import "../../chunk-GASBX52O.js";
17
+ import "../../chunk-YEGHUODU.js";
16
18
  import "../../chunk-LKGVSM2O.js";
17
19
  import {
18
20
  recordFleetEventsBestEffort
19
21
  } from "../../chunk-OTBA7DON.js";
20
22
  import "../../chunk-PH3AGF4Z.js";
21
23
  import "../../chunk-HIN3P4ZN.js";
22
- import "../../chunk-GASBX52O.js";
23
- import "../../chunk-YEGHUODU.js";
24
24
  import "../../chunk-FDIFTIXC.js";
25
25
  import "../../chunk-HVOOCK6L.js";
26
26
  import "../../chunk-XXTZBPUY.js";
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Load-aware page readiness for splash screens and intro overlays.
3
+ *
4
+ * Every splash in the fleet today hides the page behind a blind `setTimeout`,
5
+ * which punishes fast loads (a fully-painted page sits under an opaque cover
6
+ * for the full timer) and can still under-shoot slow ones. `whenPageReady`
7
+ * replaces the timer with real signals — eager-image settlement, document
8
+ * load, caller-supplied promises — bracketed by a floor (`minMs`, so a brand
9
+ * moment never flashes) and a ceiling (`maxMs`, so a stalled resource can
10
+ * never wedge the splash open).
11
+ *
12
+ * Framework-free and SSR-safe: with no DOM present it resolves immediately
13
+ * with reason "no-dom", so it can be called unguarded from universal code.
14
+ * The `env` parameter exists for tests (vitest runs in a node environment);
15
+ * production callers omit it and the globals are used.
16
+ *
17
+ * Local structural types stand in for DOM lib types because this package
18
+ * compiles with `lib: ["ES2022"]` and no DOM — same approach as
19
+ * src/configs/svelte.ts, which declares minimal shapes to avoid a peer dep.
20
+ */
21
+ type ListenerTarget = {
22
+ addEventListener(type: string, listener: () => void, options?: {
23
+ once?: boolean;
24
+ }): void;
25
+ };
26
+ type ImageLike = ListenerTarget & {
27
+ /** True once the load attempt is terminal — fires for both success AND error. */
28
+ complete: boolean;
29
+ };
30
+ type DocumentLike = ListenerTarget & {
31
+ readyState: string;
32
+ querySelectorAll(selector: string): ArrayLike<ImageLike>;
33
+ };
34
+ type WindowLike = ListenerTarget & {
35
+ matchMedia?(query: string): {
36
+ matches: boolean;
37
+ };
38
+ };
39
+ type PageReadyEnv = {
40
+ document?: DocumentLike | undefined;
41
+ window?: WindowLike | undefined;
42
+ };
43
+ type PageReadyOptions = {
44
+ /** Never resolve before this many ms — keeps a splash from flashing. Default 400. */
45
+ minMs?: number;
46
+ /** Always resolve by this many ms, loaded or not. Default 2500. */
47
+ maxMs?: number;
48
+ /**
49
+ * Selector for images that must settle (load OR error) before the page
50
+ * counts as ready. Defaults to `img[loading="eager"]` — above-the-fold
51
+ * imagery. Pass `false` to skip image tracking.
52
+ */
53
+ waitForImages?: string | false;
54
+ /**
55
+ * Also wait for `document.readyState === "complete"` (the window `load`
56
+ * event). Default false: full load includes every iframe and third-party
57
+ * script, which routinely lags the meaningful first paint by seconds —
58
+ * eager images are usually the right signal for a splash.
59
+ */
60
+ waitForDocument?: boolean;
61
+ /** Extra readiness signals (e.g. a video poster decode). Rejections count as settled. */
62
+ signals?: ReadonlyArray<Promise<unknown>>;
63
+ };
64
+ type PageReadyReason = "ready" | "timeout" | "no-dom";
65
+ /**
66
+ * Resolve when the page is visually ready — or at `maxMs`, whichever comes
67
+ * first — but never before `minMs`. The returned reason says which path won.
68
+ *
69
+ * @example Reveal a splash overlay when the hero has painted:
70
+ * ```ts
71
+ * onMount(() => {
72
+ * whenPageReady({ minMs: 600, maxMs: 2400 }).then(() => (isReady = true));
73
+ * });
74
+ * ```
75
+ */
76
+ declare function whenPageReady(options?: PageReadyOptions, env?: PageReadyEnv): Promise<PageReadyReason>;
77
+ /**
78
+ * True when the user has asked the OS for reduced motion. Splash callers
79
+ * should collapse `minMs` to 0 and skip decorative fades when this is set.
80
+ * False when no DOM (SSR) or `matchMedia` is unavailable.
81
+ */
82
+ declare function prefersReducedMotion(env?: PageReadyEnv): boolean;
83
+
84
+ export { type PageReadyEnv, type PageReadyOptions, type PageReadyReason, prefersReducedMotion, whenPageReady };
@@ -0,0 +1,47 @@
1
+ // src/client/page-ready.ts
2
+ var DEFAULT_MIN_MS = 400;
3
+ var DEFAULT_MAX_MS = 2500;
4
+ var DEFAULT_IMAGE_SELECTOR = 'img[loading="eager"]';
5
+ function globals() {
6
+ return globalThis;
7
+ }
8
+ function delay(ms) {
9
+ return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
10
+ }
11
+ function documentComplete(doc, win) {
12
+ if (doc.readyState === "complete") return Promise.resolve();
13
+ return new Promise((resolve) => win.addEventListener("load", () => resolve(), { once: true }));
14
+ }
15
+ function imageSettled(img) {
16
+ if (img.complete) return Promise.resolve();
17
+ return new Promise((resolve) => {
18
+ img.addEventListener("load", () => resolve(), { once: true });
19
+ img.addEventListener("error", () => resolve(), { once: true });
20
+ });
21
+ }
22
+ function whenPageReady(options = {}, env = {}) {
23
+ const doc = env.document ?? globals().document;
24
+ const win = env.window ?? globals().window;
25
+ if (!doc || !win) return Promise.resolve("no-dom");
26
+ const minMs = options.minMs ?? DEFAULT_MIN_MS;
27
+ const maxMs = options.maxMs ?? DEFAULT_MAX_MS;
28
+ const selector = options.waitForImages ?? DEFAULT_IMAGE_SELECTOR;
29
+ const waits = [];
30
+ if (options.waitForDocument) waits.push(documentComplete(doc, win));
31
+ if (selector !== false) {
32
+ for (const img of Array.from(doc.querySelectorAll(selector))) waits.push(imageSettled(img));
33
+ }
34
+ for (const signal of options.signals ?? []) waits.push(signal.catch(() => void 0));
35
+ const ready = Promise.all(waits).then(() => "ready");
36
+ const capped = maxMs === Infinity ? ready : Promise.race([ready, delay(maxMs).then(() => "timeout")]);
37
+ return Promise.all([capped, delay(minMs)]).then(([reason]) => reason);
38
+ }
39
+ function prefersReducedMotion(env = {}) {
40
+ const win = env.window ?? globals().window;
41
+ return win?.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
42
+ }
43
+ export {
44
+ prefersReducedMotion,
45
+ whenPageReady
46
+ };
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/page-ready.ts"],"sourcesContent":["/**\n * Load-aware page readiness for splash screens and intro overlays.\n *\n * Every splash in the fleet today hides the page behind a blind `setTimeout`,\n * which punishes fast loads (a fully-painted page sits under an opaque cover\n * for the full timer) and can still under-shoot slow ones. `whenPageReady`\n * replaces the timer with real signals — eager-image settlement, document\n * load, caller-supplied promises — bracketed by a floor (`minMs`, so a brand\n * moment never flashes) and a ceiling (`maxMs`, so a stalled resource can\n * never wedge the splash open).\n *\n * Framework-free and SSR-safe: with no DOM present it resolves immediately\n * with reason \"no-dom\", so it can be called unguarded from universal code.\n * The `env` parameter exists for tests (vitest runs in a node environment);\n * production callers omit it and the globals are used.\n *\n * Local structural types stand in for DOM lib types because this package\n * compiles with `lib: [\"ES2022\"]` and no DOM — same approach as\n * src/configs/svelte.ts, which declares minimal shapes to avoid a peer dep.\n */\n\ntype ListenerTarget = {\n addEventListener(type: string, listener: () => void, options?: { once?: boolean }): void;\n};\n\ntype ImageLike = ListenerTarget & {\n /** True once the load attempt is terminal — fires for both success AND error. */\n complete: boolean;\n};\n\ntype DocumentLike = ListenerTarget & {\n readyState: string;\n querySelectorAll(selector: string): ArrayLike<ImageLike>;\n};\n\ntype WindowLike = ListenerTarget & {\n matchMedia?(query: string): { matches: boolean };\n};\n\nexport type PageReadyEnv = {\n document?: DocumentLike | undefined;\n window?: WindowLike | undefined;\n};\n\nexport type PageReadyOptions = {\n /** Never resolve before this many ms — keeps a splash from flashing. Default 400. */\n minMs?: number;\n /** Always resolve by this many ms, loaded or not. Default 2500. */\n maxMs?: number;\n /**\n * Selector for images that must settle (load OR error) before the page\n * counts as ready. Defaults to `img[loading=\"eager\"]` — above-the-fold\n * imagery. Pass `false` to skip image tracking.\n */\n waitForImages?: string | false;\n /**\n * Also wait for `document.readyState === \"complete\"` (the window `load`\n * event). Default false: full load includes every iframe and third-party\n * script, which routinely lags the meaningful first paint by seconds —\n * eager images are usually the right signal for a splash.\n */\n waitForDocument?: boolean;\n /** Extra readiness signals (e.g. a video poster decode). Rejections count as settled. */\n signals?: ReadonlyArray<Promise<unknown>>;\n};\n\nexport type PageReadyReason = \"ready\" | \"timeout\" | \"no-dom\";\n\nconst DEFAULT_MIN_MS = 400;\nconst DEFAULT_MAX_MS = 2500;\nconst DEFAULT_IMAGE_SELECTOR = 'img[loading=\"eager\"]';\n\nfunction globals(): PageReadyEnv {\n return globalThis as unknown as PageReadyEnv;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));\n}\n\nfunction documentComplete(doc: DocumentLike, win: WindowLike): Promise<void> {\n if (doc.readyState === \"complete\") return Promise.resolve();\n return new Promise((resolve) => win.addEventListener(\"load\", () => resolve(), { once: true }));\n}\n\nfunction imageSettled(img: ImageLike): Promise<void> {\n if (img.complete) return Promise.resolve();\n return new Promise((resolve) => {\n img.addEventListener(\"load\", () => resolve(), { once: true });\n img.addEventListener(\"error\", () => resolve(), { once: true });\n });\n}\n\n/**\n * Resolve when the page is visually ready — or at `maxMs`, whichever comes\n * first — but never before `minMs`. The returned reason says which path won.\n *\n * @example Reveal a splash overlay when the hero has painted:\n * ```ts\n * onMount(() => {\n * whenPageReady({ minMs: 600, maxMs: 2400 }).then(() => (isReady = true));\n * });\n * ```\n */\nexport function whenPageReady(\n options: PageReadyOptions = {},\n env: PageReadyEnv = {},\n): Promise<PageReadyReason> {\n const doc = env.document ?? globals().document;\n const win = env.window ?? globals().window;\n if (!doc || !win) return Promise.resolve(\"no-dom\");\n\n const minMs = options.minMs ?? DEFAULT_MIN_MS;\n const maxMs = options.maxMs ?? DEFAULT_MAX_MS;\n const selector = options.waitForImages ?? DEFAULT_IMAGE_SELECTOR;\n\n const waits: Promise<unknown>[] = [];\n if (options.waitForDocument) waits.push(documentComplete(doc, win));\n if (selector !== false) {\n for (const img of Array.from(doc.querySelectorAll(selector))) waits.push(imageSettled(img));\n }\n for (const signal of options.signals ?? []) waits.push(signal.catch(() => undefined));\n\n const ready = Promise.all(waits).then<PageReadyReason>(() => \"ready\");\n const capped =\n maxMs === Infinity\n ? ready\n : Promise.race([ready, delay(maxMs).then<PageReadyReason>(() => \"timeout\")]);\n\n return Promise.all([capped, delay(minMs)]).then(([reason]) => reason);\n}\n\n/**\n * True when the user has asked the OS for reduced motion. Splash callers\n * should collapse `minMs` to 0 and skip decorative fades when this is set.\n * False when no DOM (SSR) or `matchMedia` is unavailable.\n */\nexport function prefersReducedMotion(env: PageReadyEnv = {}): boolean {\n const win = env.window ?? globals().window;\n return win?.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches ?? false;\n}\n"],"mappings":";AAoEA,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,yBAAyB;AAE/B,SAAS,UAAwB;AAC/B,SAAO;AACT;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AACtE;AAEA,SAAS,iBAAiB,KAAmB,KAAgC;AAC3E,MAAI,IAAI,eAAe,WAAY,QAAO,QAAQ,QAAQ;AAC1D,SAAO,IAAI,QAAQ,CAAC,YAAY,IAAI,iBAAiB,QAAQ,MAAM,QAAQ,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC;AAC/F;AAEA,SAAS,aAAa,KAA+B;AACnD,MAAI,IAAI,SAAU,QAAO,QAAQ,QAAQ;AACzC,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,iBAAiB,QAAQ,MAAM,QAAQ,GAAG,EAAE,MAAM,KAAK,CAAC;AAC5D,QAAI,iBAAiB,SAAS,MAAM,QAAQ,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EAC/D,CAAC;AACH;AAaO,SAAS,cACd,UAA4B,CAAC,GAC7B,MAAoB,CAAC,GACK;AAC1B,QAAM,MAAM,IAAI,YAAY,QAAQ,EAAE;AACtC,QAAM,MAAM,IAAI,UAAU,QAAQ,EAAE;AACpC,MAAI,CAAC,OAAO,CAAC,IAAK,QAAO,QAAQ,QAAQ,QAAQ;AAEjD,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,WAAW,QAAQ,iBAAiB;AAE1C,QAAM,QAA4B,CAAC;AACnC,MAAI,QAAQ,gBAAiB,OAAM,KAAK,iBAAiB,KAAK,GAAG,CAAC;AAClE,MAAI,aAAa,OAAO;AACtB,eAAW,OAAO,MAAM,KAAK,IAAI,iBAAiB,QAAQ,CAAC,EAAG,OAAM,KAAK,aAAa,GAAG,CAAC;AAAA,EAC5F;AACA,aAAW,UAAU,QAAQ,WAAW,CAAC,EAAG,OAAM,KAAK,OAAO,MAAM,MAAM,MAAS,CAAC;AAEpF,QAAM,QAAQ,QAAQ,IAAI,KAAK,EAAE,KAAsB,MAAM,OAAO;AACpE,QAAM,SACJ,UAAU,WACN,QACA,QAAQ,KAAK,CAAC,OAAO,MAAM,KAAK,EAAE,KAAsB,MAAM,SAAS,CAAC,CAAC;AAE/E,SAAO,QAAQ,IAAI,CAAC,QAAQ,MAAM,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,MAAM,MAAM;AACtE;AAOO,SAAS,qBAAqB,MAAoB,CAAC,GAAY;AACpE,QAAM,MAAM,IAAI,UAAU,QAAQ,EAAE;AACpC,SAAO,KAAK,aAAa,kCAAkC,EAAE,WAAW;AAC1E;","names":[]}
@@ -9,18 +9,21 @@ import {
9
9
  diffAttention,
10
10
  readDigestState,
11
11
  writeDigestState
12
- } from "./chunk-2E2X5BCG.js";
13
- import "./chunk-MAYHLXCS.js";
12
+ } from "./chunk-AESJBEM7.js";
13
+ import "./chunk-E2GKKUEX.js";
14
14
  import "./chunk-45AUGDFR.js";
15
15
  import {
16
16
  isIdempotencyConflict
17
- } from "./chunk-H6YZBXBQ.js";
17
+ } from "./chunk-2DCA7FHZ.js";
18
18
  import "./chunk-GECESMVS.js";
19
19
  import {
20
20
  escapeHtml,
21
21
  isPendingApproval,
22
22
  listAllReports
23
23
  } from "./chunk-6JFOAPW4.js";
24
+ import {
25
+ defaultResendClient
26
+ } from "./chunk-WEKL2HYJ.js";
24
27
  import "./chunk-OTBA7DON.js";
25
28
  import "./chunk-PH3AGF4Z.js";
26
29
  import "./chunk-HIN3P4ZN.js";
@@ -33,9 +36,6 @@ import {
33
36
  openBase,
34
37
  readAirtableConfig
35
38
  } from "./chunk-HN6I2XWI.js";
36
- import {
37
- defaultResendClient
38
- } from "./chunk-WEKL2HYJ.js";
39
39
  import "./chunk-6VAL7XJT.js";
40
40
 
41
41
  // src/reports/digest.ts
@@ -235,4 +235,4 @@ export {
235
235
  renderDigestHtml,
236
236
  runDigest
237
237
  };
238
- //# sourceMappingURL=digest-J7TDG62Q.js.map
238
+ //# sourceMappingURL=digest-Q2TAQHXF.js.map
@@ -9,14 +9,14 @@ import {
9
9
  detectSignalEvents,
10
10
  fleetSweptEvent
11
11
  } from "./chunk-5L3FPQIJ.js";
12
+ import {
13
+ makeGitHub
14
+ } from "./chunk-YEGHUODU.js";
12
15
  import {
13
16
  recordFleetEventsBestEffort
14
17
  } from "./chunk-OTBA7DON.js";
15
18
  import "./chunk-PH3AGF4Z.js";
16
19
  import "./chunk-HIN3P4ZN.js";
17
- import {
18
- makeGitHub
19
- } from "./chunk-YEGHUODU.js";
20
20
  import "./chunk-HVOOCK6L.js";
21
21
  import {
22
22
  listWebsites,
@@ -134,4 +134,4 @@ export {
134
134
  githubSignalsExitCode,
135
135
  runGitHubSignalsCommand
136
136
  };
137
- //# sourceMappingURL=github-signals-PP7GWYIY.js.map
137
+ //# sourceMappingURL=github-signals-CLQC2IPY.js.map
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./chunk-2E2X5BCG.js";
1
+ import "./chunk-AESJBEM7.js";
2
2
  import {
3
3
  approveBlockers
4
- } from "./chunk-MAYHLXCS.js";
4
+ } from "./chunk-E2GKKUEX.js";
5
5
  import {
6
6
  findDueReports
7
7
  } from "./chunk-45AUGDFR.js";
@@ -12,7 +12,7 @@ import {
12
12
  DEFAULT_INIT_STEPS,
13
13
  a11yFixturesPage,
14
14
  init
15
- } from "./chunk-LCKKIJ22.js";
15
+ } from "./chunk-42KKVLYN.js";
16
16
  import {
17
17
  convertToPnpm
18
18
  } from "./chunk-2X322ZES.js";
@@ -33,7 +33,7 @@ import {
33
33
  parseAddresses,
34
34
  sendApprovedReports,
35
35
  withGlobalCc
36
- } from "./chunk-H6YZBXBQ.js";
36
+ } from "./chunk-2DCA7FHZ.js";
37
37
  import "./chunk-GECESMVS.js";
38
38
  import {
39
39
  BLURRED_CID,
@@ -46,14 +46,16 @@ import {
46
46
  renderReportHtml,
47
47
  safeUrl
48
48
  } from "./chunk-6JFOAPW4.js";
49
+ import "./chunk-WEKL2HYJ.js";
49
50
  import {
50
51
  bumpDeps
51
52
  } from "./chunk-D3DQFC32.js";
53
+ import "./chunk-QTHKOIFJ.js";
52
54
  import {
53
55
  syncConfigs
54
- } from "./chunk-XVR7UM6Z.js";
55
- import "./chunk-XKOZUVK2.js";
56
+ } from "./chunk-JNXCDUYB.js";
56
57
  import "./chunk-CASCWQQX.js";
58
+ import "./chunk-XKOZUVK2.js";
57
59
  import "./chunk-OTGB6YQO.js";
58
60
  import {
59
61
  ALL_AUDIT_NAMES,
@@ -64,13 +66,13 @@ import {
64
66
  runAudits,
65
67
  runAuditsAcross,
66
68
  securityAudit
67
- } from "./chunk-WCN54744.js";
69
+ } from "./chunk-6G7BC5SN.js";
70
+ import "./chunk-GASBX52O.js";
71
+ import "./chunk-YEGHUODU.js";
68
72
  import "./chunk-LKGVSM2O.js";
69
73
  import "./chunk-OTBA7DON.js";
70
74
  import "./chunk-PH3AGF4Z.js";
71
75
  import "./chunk-HIN3P4ZN.js";
72
- import "./chunk-GASBX52O.js";
73
- import "./chunk-YEGHUODU.js";
74
76
  import {
75
77
  fromJsonFile,
76
78
  localPath
@@ -87,11 +89,9 @@ import {
87
89
  siteSlug
88
90
  } from "./chunk-C3PDS623.js";
89
91
  import "./chunk-HN6I2XWI.js";
90
- import "./chunk-WEKL2HYJ.js";
91
92
  import "./chunk-6VAL7XJT.js";
92
93
  import "./chunk-EYODPUHV.js";
93
94
  import "./chunk-LYCKN7ZR.js";
94
- import "./chunk-QTHKOIFJ.js";
95
95
 
96
96
  // src/recipes/index.ts
97
97
  var ALL_RECIPE_NAMES = [
@@ -8,19 +8,19 @@ import {
8
8
  } from "./chunk-YQMYQAJX.js";
9
9
  import {
10
10
  init
11
- } from "./chunk-LCKKIJ22.js";
11
+ } from "./chunk-42KKVLYN.js";
12
12
  import "./chunk-2X322ZES.js";
13
13
  import "./chunk-BTEBRTW4.js";
14
14
  import "./chunk-J7SZQUCW.js";
15
15
  import "./chunk-ZYBOT5PM.js";
16
- import "./chunk-XVR7UM6Z.js";
17
- import "./chunk-XKOZUVK2.js";
16
+ import "./chunk-JNXCDUYB.js";
18
17
  import "./chunk-CASCWQQX.js";
18
+ import "./chunk-XKOZUVK2.js";
19
19
  import "./chunk-OTGB6YQO.js";
20
- import "./chunk-WCN54744.js";
21
- import "./chunk-LKGVSM2O.js";
20
+ import "./chunk-6G7BC5SN.js";
22
21
  import "./chunk-GASBX52O.js";
23
22
  import "./chunk-YEGHUODU.js";
23
+ import "./chunk-LKGVSM2O.js";
24
24
  import "./chunk-FDIFTIXC.js";
25
25
  import "./chunk-HVOOCK6L.js";
26
26
  import {
@@ -101,4 +101,4 @@ async function runInitCommand(site, opts) {
101
101
  export {
102
102
  runInitCommand
103
103
  };
104
- //# sourceMappingURL=init-WLR35YGN.js.map
104
+ //# sourceMappingURL=init-UA6D7GKW.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ selfUpdating
3
+ } from "./chunk-IRRZG66U.js";
1
4
  import {
2
5
  writeAuditsToAirtable
3
6
  } from "./chunk-GKSXZIMX.js";
@@ -5,9 +8,6 @@ import {
5
8
  hasRealScores,
6
9
  lighthouseScoresFromResult
7
10
  } from "./chunk-XWPZ46IN.js";
8
- import {
9
- selfUpdating
10
- } from "./chunk-IRRZG66U.js";
11
11
  import "./chunk-5L3FPQIJ.js";
12
12
  import {
13
13
  resolveSites
@@ -26,10 +26,10 @@ import {
26
26
  import "./chunk-CASCWQQX.js";
27
27
  import {
28
28
  runAudits
29
- } from "./chunk-WCN54744.js";
30
- import "./chunk-LKGVSM2O.js";
29
+ } from "./chunk-6G7BC5SN.js";
31
30
  import "./chunk-GASBX52O.js";
32
31
  import "./chunk-YEGHUODU.js";
32
+ import "./chunk-LKGVSM2O.js";
33
33
  import "./chunk-FDIFTIXC.js";
34
34
  import "./chunk-HVOOCK6L.js";
35
35
  import {
@@ -210,4 +210,4 @@ async function runLaunchCommand(site, opts) {
210
210
  export {
211
211
  runLaunchCommand
212
212
  };
213
- //# sourceMappingURL=launch-2HPQXWII.js.map
213
+ //# sourceMappingURL=launch-AENAS2O2.js.map
@@ -4,16 +4,16 @@ import {
4
4
  parseAddresses,
5
5
  sendApprovedReports,
6
6
  withGlobalCc
7
- } from "./chunk-H6YZBXBQ.js";
7
+ } from "./chunk-2DCA7FHZ.js";
8
8
  import "./chunk-GECESMVS.js";
9
9
  import "./chunk-6JFOAPW4.js";
10
+ import "./chunk-WEKL2HYJ.js";
10
11
  import "./chunk-OTBA7DON.js";
11
12
  import "./chunk-PH3AGF4Z.js";
12
13
  import "./chunk-HIN3P4ZN.js";
13
14
  import "./chunk-U5SZ4FOP.js";
14
15
  import "./chunk-C3PDS623.js";
15
16
  import "./chunk-HN6I2XWI.js";
16
- import "./chunk-WEKL2HYJ.js";
17
17
  import "./chunk-6VAL7XJT.js";
18
18
  export {
19
19
  GLOBAL_REPORT_CC,
@@ -22,4 +22,4 @@ export {
22
22
  sendApprovedReports,
23
23
  withGlobalCc
24
24
  };
25
- //# sourceMappingURL=orchestrate-PVCGBH4K.js.map
25
+ //# sourceMappingURL=orchestrate-GADNFGDH.js.map
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  preflight
3
- } from "./chunk-MAYHLXCS.js";
3
+ } from "./chunk-E2GKKUEX.js";
4
4
  import "./chunk-45AUGDFR.js";
5
- import "./chunk-H6YZBXBQ.js";
5
+ import "./chunk-2DCA7FHZ.js";
6
6
  import "./chunk-GECESMVS.js";
7
7
  import "./chunk-6JFOAPW4.js";
8
+ import "./chunk-WEKL2HYJ.js";
8
9
  import "./chunk-OTBA7DON.js";
9
10
  import "./chunk-PH3AGF4Z.js";
10
11
  import "./chunk-HIN3P4ZN.js";
11
12
  import "./chunk-U5SZ4FOP.js";
12
13
  import "./chunk-C3PDS623.js";
13
14
  import "./chunk-HN6I2XWI.js";
14
- import "./chunk-WEKL2HYJ.js";
15
15
  import "./chunk-6VAL7XJT.js";
16
16
 
17
17
  // src/cli/commands/preflight.ts
@@ -61,4 +61,4 @@ async function runPreflightCommand(site, opts) {
61
61
  export {
62
62
  runPreflightCommand
63
63
  };
64
- //# sourceMappingURL=preflight-KWVYJ2DU.js.map
64
+ //# sourceMappingURL=preflight-D5RQGX4V.js.map
@@ -2,9 +2,9 @@ import {
2
2
  ALL_CONFIG_NAMES,
3
3
  isConfigName,
4
4
  syncConfigs
5
- } from "../chunk-XVR7UM6Z.js";
6
- import "../chunk-XKOZUVK2.js";
5
+ } from "../chunk-JNXCDUYB.js";
7
6
  import "../chunk-CASCWQQX.js";
7
+ import "../chunk-XKOZUVK2.js";
8
8
  import "../chunk-XXTZBPUY.js";
9
9
  import "../chunk-XTK5VIQB.js";
10
10
  export {
@@ -69,11 +69,11 @@ function dashboardBaseUrl() {
69
69
  }
70
70
  async function runReportCommand(slug, opts) {
71
71
  if (opts.digest) {
72
- const { runDigest } = await import("./digest-J7TDG62Q.js");
72
+ const { runDigest } = await import("./digest-Q2TAQHXF.js");
73
73
  return runDigest({ baseUrl: dashboardBaseUrl() });
74
74
  }
75
75
  if (opts.sendReady) {
76
- const { sendApprovedReports } = await import("./orchestrate-PVCGBH4K.js");
76
+ const { sendApprovedReports } = await import("./orchestrate-GADNFGDH.js");
77
77
  return sendApprovedReports();
78
78
  }
79
79
  if (opts.due) {
@@ -252,4 +252,4 @@ export {
252
252
  parseSingleSiteReportType,
253
253
  runReportCommand
254
254
  };
255
- //# sourceMappingURL=report-ZBFMTT76.js.map
255
+ //# sourceMappingURL=report-3FJ224H5.js.map
@@ -9,11 +9,14 @@ import {
9
9
  parseAddresses,
10
10
  prepareHeaderImage,
11
11
  renderReportEmail
12
- } from "./chunk-H6YZBXBQ.js";
12
+ } from "./chunk-2DCA7FHZ.js";
13
13
  import "./chunk-GECESMVS.js";
14
14
  import {
15
15
  fetchAttachmentBytes
16
16
  } from "./chunk-6JFOAPW4.js";
17
+ import {
18
+ defaultResendClient
19
+ } from "./chunk-WEKL2HYJ.js";
17
20
  import "./chunk-OTBA7DON.js";
18
21
  import "./chunk-PH3AGF4Z.js";
19
22
  import "./chunk-HIN3P4ZN.js";
@@ -26,9 +29,6 @@ import {
26
29
  openBase,
27
30
  readAirtableConfig
28
31
  } from "./chunk-HN6I2XWI.js";
29
- import {
30
- defaultResendClient
31
- } from "./chunk-WEKL2HYJ.js";
32
32
  import "./chunk-6VAL7XJT.js";
33
33
 
34
34
  // src/recipes/selftest-email.ts
@@ -156,4 +156,4 @@ async function runSelftestCommand(kind, site, opts) {
156
156
  export {
157
157
  runSelftestCommand
158
158
  };
159
- //# sourceMappingURL=selftest-LFZPZRJP.js.map
159
+ //# sourceMappingURL=selftest-55OJIWEB.js.map
@@ -15,12 +15,12 @@ import {
15
15
  isConfigName,
16
16
  mergeGitignore,
17
17
  syncConfigs
18
- } from "./chunk-XVR7UM6Z.js";
19
- import "./chunk-XKOZUVK2.js";
18
+ } from "./chunk-JNXCDUYB.js";
20
19
  import {
21
20
  ALL_TEMPLATES,
22
21
  templatesByName
23
22
  } from "./chunk-CASCWQQX.js";
23
+ import "./chunk-XKOZUVK2.js";
24
24
  import "./chunk-FDIFTIXC.js";
25
25
  import "./chunk-HVOOCK6L.js";
26
26
  import "./chunk-XXTZBPUY.js";
@@ -112,4 +112,4 @@ async function runSyncConfigsCommand(site, opts) {
112
112
  export {
113
113
  runSyncConfigsCommand
114
114
  };
115
- //# sourceMappingURL=sync-configs-6GBZLGRQ.js.map
115
+ //# sourceMappingURL=sync-configs-TIBO6DUJ.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reddoorla/maintenance",
3
- "version": "0.68.0",
3
+ "version": "0.69.0",
4
4
  "description": "Canonical maintenance configs, audits, and recipes for the reddoor stack.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,6 +25,10 @@
25
25
  "types": "./dist/forms/index.d.ts",
26
26
  "import": "./dist/forms/index.js"
27
27
  },
28
+ "./client": {
29
+ "types": "./dist/client/index.d.ts",
30
+ "import": "./dist/client/index.js"
31
+ },
28
32
  "./configs/lighthouse": {
29
33
  "types": "./dist/configs/lighthouse.d.ts",
30
34
  "import": "./dist/configs/lighthouse.js"