@reddoorla/maintenance 0.65.0 → 0.65.3

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 (99) hide show
  1. package/README.md +17 -10
  2. package/dist/airtable-JUPGAI4R.js +9 -0
  3. package/dist/{announce-GFLKAPTT.js → announce-WXWOHR2I.js} +24 -9
  4. package/dist/announce-WXWOHR2I.js.map +1 -0
  5. package/dist/{bump-deps-3QQHYDKJ.js → bump-deps-2MAMI7DB.js} +6 -4
  6. package/dist/bump-deps-2MAMI7DB.js.map +1 -0
  7. package/dist/{chunk-MQM5YP4J.js → chunk-ARHDSMFK.js} +2 -2
  8. package/dist/{chunk-FUD4I2ZW.js → chunk-BTEBRTW4.js} +2 -2
  9. package/dist/{chunk-7RGQ4KLE.js → chunk-CCXVX5JN.js} +5 -1
  10. package/dist/chunk-CCXVX5JN.js.map +1 -0
  11. package/dist/{chunk-4A5PYCGB.js → chunk-IMMB64VH.js} +2 -2
  12. package/dist/{chunk-UATHDNWP.js → chunk-IRRZG66U.js} +13 -6
  13. package/dist/chunk-IRRZG66U.js.map +1 -0
  14. package/dist/{chunk-OQPMZ6BM.js → chunk-J7SZQUCW.js} +10 -2
  15. package/dist/{chunk-OQPMZ6BM.js.map → chunk-J7SZQUCW.js.map} +1 -1
  16. package/dist/{chunk-M5LX2VSR.js → chunk-JWA4FO2J.js} +3 -3
  17. package/dist/{chunk-FX3QBSUF.js → chunk-LCKKIJ22.js} +3 -3
  18. package/dist/{chunk-LM42CATB.js → chunk-MEP6PR32.js} +5 -4
  19. package/dist/chunk-MEP6PR32.js.map +1 -0
  20. package/dist/{chunk-CSTLFSGM.js → chunk-N5MZ6WRX.js} +2 -2
  21. package/dist/{chunk-OYN6H4CX.js → chunk-PMIKXAPF.js} +4 -4
  22. package/dist/{chunk-U3MF6RCS.js → chunk-SYTPVYIK.js} +13 -14
  23. package/dist/chunk-SYTPVYIK.js.map +1 -0
  24. package/dist/chunk-VPJ7N6P7.js +27 -0
  25. package/dist/chunk-VPJ7N6P7.js.map +1 -0
  26. package/dist/{chunk-FH7WQHD7.js → chunk-VUKSRWRD.js} +2 -2
  27. package/dist/{chunk-TC7Z5LG7.js → chunk-WCN54744.js} +30 -16
  28. package/dist/{chunk-TC7Z5LG7.js.map → chunk-WCN54744.js.map} +1 -1
  29. package/dist/{chunk-QSL3EJGI.js → chunk-WXNSLK4Q.js} +3 -3
  30. package/dist/{chunk-4GACMVNE.js → chunk-YEGHUODU.js} +17 -1
  31. package/dist/chunk-YEGHUODU.js.map +1 -0
  32. package/dist/{chunk-O65I7G7G.js → chunk-ZO7WNY57.js} +2 -2
  33. package/dist/cli/bin.js +14 -14
  34. package/dist/cli/commands/audit.js +7 -7
  35. package/dist/{convert-to-pnpm-ZO673UFB.js → convert-to-pnpm-3OEHYF76.js} +6 -4
  36. package/dist/convert-to-pnpm-3OEHYF76.js.map +1 -0
  37. package/dist/{digest-R3ROSGLP.js → digest-BTHXYYQZ.js} +3 -3
  38. package/dist/{github-signals-N5JGWHW2.js → github-signals-H7VU4EOH.js} +5 -5
  39. package/dist/index.d.ts +29 -7
  40. package/dist/index.js +16 -16
  41. package/dist/index.js.map +1 -1
  42. package/dist/{init-FOHNISF2.js → init-VA3H4OHM.js} +26 -9
  43. package/dist/init-VA3H4OHM.js.map +1 -0
  44. package/dist/{launch-TM3IHSSU.js → launch-OMHMW5OK.js} +9 -9
  45. package/dist/{lighthouse-airtable-5FHELRCA.js → lighthouse-airtable-4KWC3P72.js} +3 -3
  46. package/dist/{onboard-K2EL4MSG.js → onboard-2PLVVJWN.js} +10 -6
  47. package/dist/onboard-2PLVVJWN.js.map +1 -0
  48. package/dist/{orchestrate-OX3Z4DUI.js → orchestrate-6PKHJXLF.js} +4 -4
  49. package/dist/{renovate-dispatch-H25CQ36P.js → renovate-dispatch-K6VO5KWM.js} +3 -3
  50. package/dist/{report-UEYKO6WH.js → report-X3XPBRBO.js} +6 -6
  51. package/dist/reports/maintenance-email/assets/blurredTests.jpg +0 -0
  52. package/dist/{self-updating-YXOGQWH5.js → self-updating-VXVJSV5T.js} +8 -6
  53. package/dist/self-updating-VXVJSV5T.js.map +1 -0
  54. package/dist/{selftest-VE7CSGWE.js → selftest-FV4MO7TX.js} +6 -6
  55. package/dist/{svelte-codemods-745QM25J.js → svelte-codemods-5RXRRTMK.js} +8 -6
  56. package/dist/svelte-codemods-5RXRRTMK.js.map +1 -0
  57. package/dist/{sync-configs-NYC3Z625.js → sync-configs-TPJMRNRU.js} +10 -4
  58. package/dist/sync-configs-TPJMRNRU.js.map +1 -0
  59. package/dist/{upgrade-UBPPJ6HN.js → upgrade-7TN2XPFK.js} +8 -10
  60. package/dist/upgrade-7TN2XPFK.js.map +1 -0
  61. package/dist/{websites-CSVLSEVL.js → websites-EIPNY4DY.js} +2 -2
  62. package/dist/{write-audits-to-airtable-JCV7FYAW.js → write-audits-to-airtable-WVWFESZW.js} +4 -4
  63. package/package.json +1 -1
  64. package/dist/airtable-GGZJUGQB.js +0 -9
  65. package/dist/announce-GFLKAPTT.js.map +0 -1
  66. package/dist/bump-deps-3QQHYDKJ.js.map +0 -1
  67. package/dist/chunk-4GACMVNE.js.map +0 -1
  68. package/dist/chunk-7RGQ4KLE.js.map +0 -1
  69. package/dist/chunk-LM42CATB.js.map +0 -1
  70. package/dist/chunk-U3MF6RCS.js.map +0 -1
  71. package/dist/chunk-UATHDNWP.js.map +0 -1
  72. package/dist/convert-to-pnpm-ZO673UFB.js.map +0 -1
  73. package/dist/init-FOHNISF2.js.map +0 -1
  74. package/dist/onboard-K2EL4MSG.js.map +0 -1
  75. package/dist/self-updating-YXOGQWH5.js.map +0 -1
  76. package/dist/svelte-codemods-745QM25J.js.map +0 -1
  77. package/dist/sync-configs-NYC3Z625.js.map +0 -1
  78. package/dist/upgrade-UBPPJ6HN.js.map +0 -1
  79. /package/dist/{airtable-GGZJUGQB.js.map → airtable-JUPGAI4R.js.map} +0 -0
  80. /package/dist/{chunk-MQM5YP4J.js.map → chunk-ARHDSMFK.js.map} +0 -0
  81. /package/dist/{chunk-FUD4I2ZW.js.map → chunk-BTEBRTW4.js.map} +0 -0
  82. /package/dist/{chunk-4A5PYCGB.js.map → chunk-IMMB64VH.js.map} +0 -0
  83. /package/dist/{chunk-M5LX2VSR.js.map → chunk-JWA4FO2J.js.map} +0 -0
  84. /package/dist/{chunk-FX3QBSUF.js.map → chunk-LCKKIJ22.js.map} +0 -0
  85. /package/dist/{chunk-CSTLFSGM.js.map → chunk-N5MZ6WRX.js.map} +0 -0
  86. /package/dist/{chunk-OYN6H4CX.js.map → chunk-PMIKXAPF.js.map} +0 -0
  87. /package/dist/{chunk-FH7WQHD7.js.map → chunk-VUKSRWRD.js.map} +0 -0
  88. /package/dist/{chunk-QSL3EJGI.js.map → chunk-WXNSLK4Q.js.map} +0 -0
  89. /package/dist/{chunk-O65I7G7G.js.map → chunk-ZO7WNY57.js.map} +0 -0
  90. /package/dist/{digest-R3ROSGLP.js.map → digest-BTHXYYQZ.js.map} +0 -0
  91. /package/dist/{github-signals-N5JGWHW2.js.map → github-signals-H7VU4EOH.js.map} +0 -0
  92. /package/dist/{launch-TM3IHSSU.js.map → launch-OMHMW5OK.js.map} +0 -0
  93. /package/dist/{lighthouse-airtable-5FHELRCA.js.map → lighthouse-airtable-4KWC3P72.js.map} +0 -0
  94. /package/dist/{orchestrate-OX3Z4DUI.js.map → orchestrate-6PKHJXLF.js.map} +0 -0
  95. /package/dist/{renovate-dispatch-H25CQ36P.js.map → renovate-dispatch-K6VO5KWM.js.map} +0 -0
  96. /package/dist/{report-UEYKO6WH.js.map → report-X3XPBRBO.js.map} +0 -0
  97. /package/dist/{selftest-VE7CSGWE.js.map → selftest-FV4MO7TX.js.map} +0 -0
  98. /package/dist/{websites-CSVLSEVL.js.map → websites-EIPNY4DY.js.map} +0 -0
  99. /package/dist/{write-audits-to-airtable-JCV7FYAW.js.map → write-audits-to-airtable-WVWFESZW.js.map} +0 -0
@@ -5,25 +5,27 @@ import {
5
5
  } from "./chunk-4NAOR44V.js";
6
6
  import {
7
7
  resolveSites
8
- } from "./chunk-FH7WQHD7.js";
8
+ } from "./chunk-VUKSRWRD.js";
9
9
  import {
10
10
  init
11
- } from "./chunk-FX3QBSUF.js";
11
+ } from "./chunk-LCKKIJ22.js";
12
12
  import "./chunk-2X322ZES.js";
13
- import "./chunk-FUD4I2ZW.js";
14
- import "./chunk-OQPMZ6BM.js";
13
+ import "./chunk-BTEBRTW4.js";
14
+ import "./chunk-J7SZQUCW.js";
15
15
  import "./chunk-ZYBOT5PM.js";
16
16
  import "./chunk-XVR7UM6Z.js";
17
17
  import "./chunk-XKOZUVK2.js";
18
18
  import "./chunk-CASCWQQX.js";
19
19
  import "./chunk-OTGB6YQO.js";
20
- import "./chunk-TC7Z5LG7.js";
20
+ import "./chunk-WCN54744.js";
21
21
  import "./chunk-LKGVSM2O.js";
22
22
  import "./chunk-GASBX52O.js";
23
- import "./chunk-4GACMVNE.js";
23
+ import "./chunk-YEGHUODU.js";
24
24
  import "./chunk-FDIFTIXC.js";
25
25
  import "./chunk-HVOOCK6L.js";
26
- import "./chunk-XXTZBPUY.js";
26
+ import {
27
+ siteLabel
28
+ } from "./chunk-XXTZBPUY.js";
27
29
  import "./chunk-XTK5VIQB.js";
28
30
  import "./chunk-U5SZ4FOP.js";
29
31
  import "./chunk-EYODPUHV.js";
@@ -76,7 +78,22 @@ async function runInitCommand(site, opts) {
76
78
  skipped = prep.skipped;
77
79
  }
78
80
  const results = [];
79
- for (const s of sites) results.push(await init(s));
81
+ for (const s of sites) {
82
+ try {
83
+ results.push(await init(s));
84
+ } catch (err) {
85
+ results.push({
86
+ site: siteLabel(s),
87
+ steps: [
88
+ {
89
+ name: "init",
90
+ result: { kind: "error", message: err instanceof Error ? err.message : String(err) }
91
+ }
92
+ ],
93
+ complete: false
94
+ });
95
+ }
96
+ }
80
97
  const output = results.map(formatResult).join("\n\n");
81
98
  const code = results.some((r) => exitCodeFor(r) !== 0) ? 1 : 0;
82
99
  return { output: appendSkipNotice(output, skipped), code };
@@ -84,4 +101,4 @@ async function runInitCommand(site, opts) {
84
101
  export {
85
102
  runInitCommand
86
103
  };
87
- //# sourceMappingURL=init-FOHNISF2.js.map
104
+ //# sourceMappingURL=init-VA3H4OHM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/init.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { init, type InitResult, type InitStepResult } from \"../../recipes/init.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\nimport { siteLabel } from \"../../util/site.js\";\n\nexport type InitCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatStep(name: string, r: InitStepResult): string {\n if (r.kind === \"error\") return `${name.padEnd(20)} error: ${r.message}`;\n if (r.kind === \"audit\") {\n const lines = r.results.map(\n (a) => ` ${a.audit.padEnd(12)} ${a.status.padEnd(5)} ${a.summary}`,\n );\n return `${name.padEnd(20)} ${r.results.length} audit(s):\\n${lines.join(\"\\n\")}`;\n }\n const rec = r.result;\n if (rec.status === \"noop\") return `${name.padEnd(20)} noop${rec.notes ? ` — ${rec.notes}` : \"\"}`;\n if (rec.status === \"failed\")\n return `${name.padEnd(20)} failed${rec.notes ? ` — ${rec.notes}` : \"\"}`;\n return `${name.padEnd(20)} applied (${rec.commits.length} commit${rec.commits.length === 1 ? \"\" : \"s\"})${rec.notes ? ` — ${rec.notes}` : \"\"}`;\n}\n\nfunction formatResult(r: InitResult): string {\n const header = `[${r.site}] init — ${r.complete ? \"complete\" : \"STOPPED\"}`;\n const body = r.steps.map((s) => formatStep(s.name, s.result)).join(\"\\n\");\n return `${header}\\n${body}`;\n}\n\nfunction exitCodeFor(r: InitResult): number {\n if (!r.complete) return 1;\n // A complete chain can still surface a failing audit at the end. Treat\n // any `fail`-status audit as exit 1 so CI signals a regression even when\n // every recipe applied cleanly.\n for (const step of r.steps) {\n if (step.result.kind === \"audit\" && step.result.results.some((a) => a.status === \"fail\")) {\n return 1;\n }\n }\n return 0;\n}\n\nexport async function runInitCommand(\n site: string | undefined,\n opts: InitCommandOptions,\n): Promise<{ output: string; code: number }> {\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results: InitResult[] = [];\n for (const s of sites) {\n try {\n results.push(await init(s));\n } catch (err) {\n // Isolate a per-site throw (e.g. a transient git error) so the rest of the\n // fleet still runs — the same guarantee `runRecipeOverSites` gives the other\n // fleet commands, but `init` returns an `InitResult`, so synthesize a stopped\n // one here rather than reuse the shared helper.\n results.push({\n site: siteLabel(s),\n steps: [\n {\n name: \"init\",\n result: { kind: \"error\", message: err instanceof Error ? err.message : String(err) },\n },\n ],\n complete: false,\n });\n }\n }\n\n const output = results.map(formatResult).join(\"\\n\\n\");\n const code = results.some((r) => exitCodeFor(r) !== 0) ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":"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","names":[]}
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  writeAuditsToAirtable
3
- } from "./chunk-LM42CATB.js";
3
+ } from "./chunk-MEP6PR32.js";
4
4
  import {
5
5
  hasRealScores,
6
6
  lighthouseScoresFromResult
7
- } from "./chunk-CSTLFSGM.js";
7
+ } from "./chunk-N5MZ6WRX.js";
8
8
  import {
9
9
  selfUpdating
10
- } from "./chunk-UATHDNWP.js";
10
+ } from "./chunk-IRRZG66U.js";
11
11
  import "./chunk-5L3FPQIJ.js";
12
12
  import {
13
13
  resolveSites
14
- } from "./chunk-FH7WQHD7.js";
14
+ } from "./chunk-VUKSRWRD.js";
15
15
  import {
16
16
  queueDraft
17
17
  } from "./chunk-6LIWDIXU.js";
@@ -19,7 +19,7 @@ import {
19
19
  renderReportHtml,
20
20
  resolveCopy,
21
21
  uploadAttachment
22
- } from "./chunk-U3MF6RCS.js";
22
+ } from "./chunk-SYTPVYIK.js";
23
23
  import {
24
24
  createDraft,
25
25
  findReportByPeriod,
@@ -28,10 +28,10 @@ import {
28
28
  import "./chunk-CASCWQQX.js";
29
29
  import {
30
30
  runAudits
31
- } from "./chunk-TC7Z5LG7.js";
31
+ } from "./chunk-WCN54744.js";
32
32
  import "./chunk-LKGVSM2O.js";
33
33
  import "./chunk-GASBX52O.js";
34
- import "./chunk-4GACMVNE.js";
34
+ import "./chunk-YEGHUODU.js";
35
35
  import "./chunk-FDIFTIXC.js";
36
36
  import "./chunk-HVOOCK6L.js";
37
37
  import {
@@ -42,7 +42,7 @@ import "./chunk-U5SZ4FOP.js";
42
42
  import {
43
43
  listWebsites,
44
44
  siteSlug
45
- } from "./chunk-7RGQ4KLE.js";
45
+ } from "./chunk-CCXVX5JN.js";
46
46
  import {
47
47
  openBase,
48
48
  readAirtableConfig
@@ -212,4 +212,4 @@ async function runLaunchCommand(site, opts) {
212
212
  export {
213
213
  runLaunchCommand
214
214
  };
215
- //# sourceMappingURL=launch-TM3IHSSU.js.map
215
+ //# sourceMappingURL=launch-OMHMW5OK.js.map
@@ -2,11 +2,11 @@ import {
2
2
  hasRealScores,
3
3
  lighthouseScoresFromResult,
4
4
  resolveSlugFromCwd
5
- } from "./chunk-CSTLFSGM.js";
6
- import "./chunk-7RGQ4KLE.js";
5
+ } from "./chunk-N5MZ6WRX.js";
6
+ import "./chunk-CCXVX5JN.js";
7
7
  export {
8
8
  hasRealScores,
9
9
  lighthouseScoresFromResult,
10
10
  resolveSlugFromCwd
11
11
  };
12
- //# sourceMappingURL=lighthouse-airtable-5FHELRCA.js.map
12
+ //# sourceMappingURL=lighthouse-airtable-4KWC3P72.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ runRecipeOverSites
3
+ } from "./chunk-VPJ7N6P7.js";
1
4
  import {
2
5
  appendSkipNotice,
3
6
  fleetWorkdir,
@@ -5,7 +8,7 @@ import {
5
8
  } from "./chunk-4NAOR44V.js";
6
9
  import {
7
10
  resolveSites
8
- } from "./chunk-FH7WQHD7.js";
11
+ } from "./chunk-VUKSRWRD.js";
9
12
  import {
10
13
  onboard
11
14
  } from "./chunk-ZYBOT5PM.js";
@@ -55,10 +58,11 @@ async function runOnboardCommand(site, opts) {
55
58
  sites = prep.prepared;
56
59
  skipped = prep.skipped;
57
60
  }
58
- const results = [];
59
- for (const s of sites) {
60
- results.push(await onboard(s, audits ? { audits } : {}));
61
- }
61
+ const results = await runRecipeOverSites(
62
+ "onboard",
63
+ sites,
64
+ (s) => onboard(s, audits ? { audits } : {})
65
+ );
62
66
  const output = results.map(formatResult).join("\n");
63
67
  const code = results.some((r) => r.status === "failed") ? 1 : 0;
64
68
  return { output: appendSkipNotice(output, skipped), code };
@@ -66,4 +70,4 @@ async function runOnboardCommand(site, opts) {
66
70
  export {
67
71
  runOnboardCommand
68
72
  };
69
- //# sourceMappingURL=onboard-K2EL4MSG.js.map
73
+ //# sourceMappingURL=onboard-2PLVVJWN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/onboard.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { onboard, type OnboardAudit } from \"../../recipes/onboard.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type OnboardCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n audits?: string;\n};\n\nconst ALL_AUDITS: OnboardAudit[] = [\"lighthouse\", \"a11y\"];\n\nfunction parseAudits(value: string | undefined): OnboardAudit[] | undefined {\n if (!value) return undefined;\n const parsed = value.split(\",\").map((s) => s.trim());\n for (const a of parsed) {\n if (!ALL_AUDITS.includes(a as OnboardAudit)) {\n throw Object.assign(\n new Error(`unknown audit in --audits: ${a}. expected ${ALL_AUDITS.join(\", \")}`),\n { exitCode: 2 },\n );\n }\n }\n return parsed as OnboardAudit[];\n}\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runOnboardCommand(\n site: string | undefined,\n opts: OnboardCommandOptions,\n): Promise<{ output: string; code: number }> {\n const audits = parseAudits(opts.audits);\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results = await runRecipeOverSites(\"onboard\", sites, (s) =>\n onboard(s, audits ? { audits } : {}),\n );\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAexB,IAAM,aAA6B,CAAC,cAAc,MAAM;AAExD,SAAS,YAAY,OAAuD;AAC1E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACnD,aAAW,KAAK,QAAQ;AACtB,QAAI,CAAC,WAAW,SAAS,CAAiB,GAAG;AAC3C,YAAM,OAAO;AAAA,QACX,IAAI,MAAM,8BAA8B,CAAC,cAAc,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,QAC9E,EAAE,UAAU,EAAE;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,MAAI,EAAE,WAAW,SAAU,QAAO,IAAI,EAAE,IAAI,aAAa,EAAE,SAAS,EAAE;AACtE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,kBACpB,MACA,MAC2C;AAC3C,QAAM,SAAS,YAAY,KAAK,MAAM;AACtC,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAAU,MAAM;AAAA,IAAmB;AAAA,IAAW;AAAA,IAAO,CAAC,MAC1D,QAAQ,GAAG,SAAS,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,EACrC;AAEA,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}
@@ -4,16 +4,16 @@ import {
4
4
  parseAddresses,
5
5
  sendApprovedReports,
6
6
  withGlobalCc
7
- } from "./chunk-QSL3EJGI.js";
7
+ } from "./chunk-WXNSLK4Q.js";
8
8
  import "./chunk-OGGRFBL4.js";
9
9
  import "./chunk-GECESMVS.js";
10
- import "./chunk-U3MF6RCS.js";
10
+ import "./chunk-SYTPVYIK.js";
11
11
  import "./chunk-OCS7SZUZ.js";
12
12
  import "./chunk-G2YRXV26.js";
13
13
  import "./chunk-PTPTVVY7.js";
14
14
  import "./chunk-XKKTK6WA.js";
15
15
  import "./chunk-U5SZ4FOP.js";
16
- import "./chunk-7RGQ4KLE.js";
16
+ import "./chunk-CCXVX5JN.js";
17
17
  import "./chunk-HN6I2XWI.js";
18
18
  import "./chunk-WEKL2HYJ.js";
19
19
  import "./chunk-6VAL7XJT.js";
@@ -24,4 +24,4 @@ export {
24
24
  sendApprovedReports,
25
25
  withGlobalCc
26
26
  };
27
- //# sourceMappingURL=orchestrate-OX3Z4DUI.js.map
27
+ //# sourceMappingURL=orchestrate-6PKHJXLF.js.map
@@ -3,13 +3,13 @@ import {
3
3
  } from "./chunk-PZQ3WED2.js";
4
4
  import {
5
5
  makeGitHub
6
- } from "./chunk-4GACMVNE.js";
6
+ } from "./chunk-YEGHUODU.js";
7
7
  import "./chunk-HVOOCK6L.js";
8
8
  import {
9
9
  isDashboardVisible,
10
10
  listWebsites,
11
11
  updateAutoFixAttempts
12
- } from "./chunk-7RGQ4KLE.js";
12
+ } from "./chunk-CCXVX5JN.js";
13
13
  import {
14
14
  openBase,
15
15
  readAirtableConfig
@@ -136,4 +136,4 @@ No active repo-backed sites with critical/high vulnerabilities \u2014 nothing to
136
136
  export {
137
137
  runRenovateDispatchCommand
138
138
  };
139
- //# sourceMappingURL=renovate-dispatch-H25CQ36P.js.map
139
+ //# sourceMappingURL=renovate-dispatch-K6VO5KWM.js.map
@@ -5,11 +5,11 @@ import {
5
5
  import {
6
6
  draftReportForSite,
7
7
  readGaConfig
8
- } from "./chunk-M5LX2VSR.js";
8
+ } from "./chunk-JWA4FO2J.js";
9
9
  import {
10
10
  reportTier
11
11
  } from "./chunk-6LIWDIXU.js";
12
- import "./chunk-U3MF6RCS.js";
12
+ import "./chunk-SYTPVYIK.js";
13
13
  import {
14
14
  escapeHtml,
15
15
  listAllReports
@@ -18,7 +18,7 @@ import "./chunk-U5SZ4FOP.js";
18
18
  import {
19
19
  listWebsites,
20
20
  siteSlug
21
- } from "./chunk-7RGQ4KLE.js";
21
+ } from "./chunk-CCXVX5JN.js";
22
22
  import {
23
23
  openBase,
24
24
  readAirtableConfig
@@ -68,11 +68,11 @@ function dashboardBaseUrl() {
68
68
  }
69
69
  async function runReportCommand(slug, opts) {
70
70
  if (opts.digest) {
71
- const { runDigest } = await import("./digest-R3ROSGLP.js");
71
+ const { runDigest } = await import("./digest-BTHXYYQZ.js");
72
72
  return runDigest({ baseUrl: dashboardBaseUrl() });
73
73
  }
74
74
  if (opts.sendReady) {
75
- const { sendApprovedReports } = await import("./orchestrate-OX3Z4DUI.js");
75
+ const { sendApprovedReports } = await import("./orchestrate-6PKHJXLF.js");
76
76
  return sendApprovedReports();
77
77
  }
78
78
  if (opts.due) {
@@ -237,4 +237,4 @@ export {
237
237
  parseSingleSiteReportType,
238
238
  runReportCommand
239
239
  };
240
- //# sourceMappingURL=report-UEYKO6WH.js.map
240
+ //# sourceMappingURL=report-X3XPBRBO.js.map
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  selfUpdating
3
- } from "./chunk-UATHDNWP.js";
3
+ } from "./chunk-IRRZG66U.js";
4
+ import {
5
+ runRecipeOverSites
6
+ } from "./chunk-VPJ7N6P7.js";
4
7
  import {
5
8
  appendSkipNotice,
6
9
  fleetWorkdir,
@@ -8,10 +11,10 @@ import {
8
11
  } from "./chunk-4NAOR44V.js";
9
12
  import {
10
13
  resolveSites
11
- } from "./chunk-FH7WQHD7.js";
14
+ } from "./chunk-VUKSRWRD.js";
12
15
  import "./chunk-CASCWQQX.js";
13
16
  import "./chunk-GASBX52O.js";
14
- import "./chunk-4GACMVNE.js";
17
+ import "./chunk-YEGHUODU.js";
15
18
  import "./chunk-FDIFTIXC.js";
16
19
  import "./chunk-HVOOCK6L.js";
17
20
  import "./chunk-XXTZBPUY.js";
@@ -49,8 +52,7 @@ async function runSelfUpdatingCommand(site, opts) {
49
52
  code: 0
50
53
  };
51
54
  }
52
- const results = [];
53
- for (const s of sites) results.push(await selfUpdating(s));
55
+ const results = await runRecipeOverSites("self-updating", sites, (s) => selfUpdating(s));
54
56
  return {
55
57
  output: appendSkipNotice(results.map(formatResult).join("\n"), skipped),
56
58
  code: results.some((r) => r.status === "failed") ? 1 : 0
@@ -59,4 +61,4 @@ async function runSelfUpdatingCommand(site, opts) {
59
61
  export {
60
62
  runSelfUpdatingCommand
61
63
  };
62
- //# sourceMappingURL=self-updating-YXOGQWH5.js.map
64
+ //# sourceMappingURL=self-updating-VXVJSV5T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/self-updating.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\nimport { selfUpdating } from \"../../recipes/self-updating/index.js\";\nimport type { RecipeResult } from \"../../types.js\";\n\nexport type SelfUpdatingCommandOptions = {\n fleet?: string;\n workdir?: string;\n dry?: boolean;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"already self-updating\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runSelfUpdatingCommand(\n site: string | undefined,\n opts: SelfUpdatingCommandOptions,\n): Promise<{ output: string; code: number }> {\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n if (opts.dry) {\n return {\n output: appendSkipNotice(\n sites.map((s) => `[${s.name || s.path}] would enable self-updating`).join(\"\\n\"),\n skipped,\n ),\n code: 0,\n };\n }\n\n const results = await runRecipeOverSites(\"self-updating\", sites, (s) => selfUpdating(s));\n\n return {\n output: appendSkipNotice(results.map(formatResult).join(\"\\n\"), skipped),\n code: results.some((r) => r.status === \"failed\") ? 1 : 0,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAexB,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,uBAAuB;AACvF,MAAI,EAAE,WAAW,SAAU,QAAO,IAAI,EAAE,IAAI,aAAa,EAAE,SAAS,EAAE;AACtE,SAAO,IAAI,EAAE,IAAI;AAAA,EAAc,EAAE,SAAS,EAAE;AAC9C;AAEA,eAAsB,uBACpB,MACA,MAC2C;AAC3C,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,MAAI,KAAK,KAAK;AACZ,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,MAAM,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,EAAE,IAAI,8BAA8B,EAAE,KAAK,IAAI;AAAA,QAC9E;AAAA,MACF;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,mBAAmB,iBAAiB,OAAO,CAAC,MAAM,aAAa,CAAC,CAAC;AAEvF,SAAO;AAAA,IACL,QAAQ,iBAAiB,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI,GAAG,OAAO;AAAA,IACtE,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAAA,EACzD;AACF;","names":[]}
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  buildReportDataForSite,
3
3
  scoresFromRow
4
- } from "./chunk-OYN6H4CX.js";
5
- import "./chunk-M5LX2VSR.js";
4
+ } from "./chunk-PMIKXAPF.js";
5
+ import "./chunk-JWA4FO2J.js";
6
6
  import "./chunk-6LIWDIXU.js";
7
7
  import {
8
8
  isProbablyEmail,
9
9
  parseAddresses,
10
10
  prepareHeaderImage,
11
11
  renderReportEmail
12
- } from "./chunk-QSL3EJGI.js";
12
+ } from "./chunk-WXNSLK4Q.js";
13
13
  import "./chunk-OGGRFBL4.js";
14
14
  import "./chunk-GECESMVS.js";
15
15
  import {
16
16
  fetchAttachmentBytes
17
- } from "./chunk-U3MF6RCS.js";
17
+ } from "./chunk-SYTPVYIK.js";
18
18
  import "./chunk-OCS7SZUZ.js";
19
19
  import "./chunk-G2YRXV26.js";
20
20
  import "./chunk-PTPTVVY7.js";
@@ -23,7 +23,7 @@ import "./chunk-U5SZ4FOP.js";
23
23
  import {
24
24
  listWebsites,
25
25
  siteSlug
26
- } from "./chunk-7RGQ4KLE.js";
26
+ } from "./chunk-CCXVX5JN.js";
27
27
  import {
28
28
  openBase,
29
29
  readAirtableConfig
@@ -158,4 +158,4 @@ async function runSelftestCommand(kind, site, opts) {
158
158
  export {
159
159
  runSelftestCommand
160
160
  };
161
- //# sourceMappingURL=selftest-VE7CSGWE.js.map
161
+ //# sourceMappingURL=selftest-FV4MO7TX.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ runRecipeOverSites
3
+ } from "./chunk-VPJ7N6P7.js";
1
4
  import {
2
5
  appendSkipNotice,
3
6
  fleetWorkdir,
@@ -5,11 +8,11 @@ import {
5
8
  } from "./chunk-4NAOR44V.js";
6
9
  import {
7
10
  resolveSites
8
- } from "./chunk-FH7WQHD7.js";
11
+ } from "./chunk-VUKSRWRD.js";
9
12
  import {
10
13
  svelteCodemods
11
- } from "./chunk-FUD4I2ZW.js";
12
- import "./chunk-OQPMZ6BM.js";
14
+ } from "./chunk-BTEBRTW4.js";
15
+ import "./chunk-J7SZQUCW.js";
13
16
  import "./chunk-XKOZUVK2.js";
14
17
  import "./chunk-FDIFTIXC.js";
15
18
  import "./chunk-HVOOCK6L.js";
@@ -39,8 +42,7 @@ async function runSvelteCodemodsCommand(site, opts) {
39
42
  sites = prep.prepared;
40
43
  skipped = prep.skipped;
41
44
  }
42
- const results = [];
43
- for (const s of sites) results.push(await svelteCodemods(s));
45
+ const results = await runRecipeOverSites("svelte-codemods", sites, (s) => svelteCodemods(s));
44
46
  const output = results.map(formatResult).join("\n");
45
47
  const code = results.some((r) => r.status === "failed") ? 1 : 0;
46
48
  return { output: appendSkipNotice(output, skipped), code };
@@ -48,4 +50,4 @@ async function runSvelteCodemodsCommand(site, opts) {
48
50
  export {
49
51
  runSvelteCodemodsCommand
50
52
  };
51
- //# sourceMappingURL=svelte-codemods-745QM25J.js.map
53
+ //# sourceMappingURL=svelte-codemods-5RXRRTMK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/svelte-codemods.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { svelteCodemods } from \"../../recipes/svelte-codemods.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type SvelteCodemodsCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n if (r.status === \"failed\") return `[${r.site}] failed: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runSvelteCodemodsCommand(\n site: string | undefined,\n opts: SvelteCodemodsCommandOptions,\n): Promise<{ output: string; code: number }> {\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results = await runRecipeOverSites(\"svelte-codemods\", sites, (s) => svelteCodemods(s));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAcxB,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,MAAI,EAAE,WAAW,SAAU,QAAO,IAAI,EAAE,IAAI,aAAa,EAAE,SAAS,EAAE;AACtE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,yBACpB,MACA,MAC2C;AAC3C,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAAU,MAAM,mBAAmB,mBAAmB,OAAO,CAAC,MAAM,eAAe,CAAC,CAAC;AAE3F,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}
@@ -1,3 +1,6 @@
1
+ import {
2
+ runRecipeOverSites
3
+ } from "./chunk-VPJ7N6P7.js";
1
4
  import {
2
5
  appendSkipNotice,
3
6
  fleetWorkdir,
@@ -5,7 +8,7 @@ import {
5
8
  } from "./chunk-4NAOR44V.js";
6
9
  import {
7
10
  resolveSites
8
- } from "./chunk-FH7WQHD7.js";
11
+ } from "./chunk-VUKSRWRD.js";
9
12
  import {
10
13
  ALL_CONFIG_NAMES,
11
14
  CANONICAL_GITIGNORE_ENTRIES,
@@ -97,8 +100,11 @@ async function runSyncConfigsCommand(site, opts) {
97
100
  }
98
101
  return { output: appendSkipNotice(blocks.join("\n\n"), skipped), code: 0 };
99
102
  }
100
- const results = [];
101
- for (const s of sites) results.push(await syncConfigs(s, which ? { which } : {}));
103
+ const results = await runRecipeOverSites(
104
+ "sync-configs",
105
+ sites,
106
+ (s) => syncConfigs(s, which ? { which } : {})
107
+ );
102
108
  const output = results.map(formatResult).join("\n");
103
109
  const code = results.some((r) => r.status === "failed") ? 1 : 0;
104
110
  return { output: appendSkipNotice(output, skipped), code };
@@ -106,4 +112,4 @@ async function runSyncConfigsCommand(site, opts) {
106
112
  export {
107
113
  runSyncConfigsCommand
108
114
  };
109
- //# sourceMappingURL=sync-configs-NYC3Z625.js.map
115
+ //# sourceMappingURL=sync-configs-TPJMRNRU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/sync-configs.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { syncConfigs, ALL_CONFIG_NAMES, isConfigName } from \"../../recipes/sync-configs.js\";\nimport { ALL_TEMPLATES, templatesByName } from \"../../recipes/sync-configs/templates.js\";\nimport {\n CANONICAL_GITIGNORE_ENTRIES,\n mergeGitignore,\n} from \"../../recipes/sync-configs/gitignore.js\";\nimport type { ConfigName, RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nexport type SyncConfigsCommandOptions = {\n only?: string;\n dry?: boolean;\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction parseOnly(value?: string): ConfigName[] | undefined {\n if (!value) return undefined;\n const names = value.split(\",\").map((s) => s.trim());\n for (const n of names) {\n if (!isConfigName(n)) {\n throw Object.assign(\n new Error(`unknown config in --only: \"${n}\". Valid: ${ALL_CONFIG_NAMES.join(\", \")}`),\n { exitCode: 2 },\n );\n }\n }\n return names as ConfigName[];\n}\n\nasync function dryPlanGitignore(cwd: string): Promise<string | null> {\n let existing: string | null;\n try {\n existing = await readFile(join(cwd, \".gitignore\"), \"utf-8\");\n } catch {\n return \"would create .gitignore\";\n }\n const merge = mergeGitignore(existing, CANONICAL_GITIGNORE_ENTRIES);\n if (merge.added.length === 0) return null;\n return `would update .gitignore (${merge.added.length} canonical entries to add)`;\n}\n\nasync function dryPlan(cwd: string, which?: ConfigName[]): Promise<string> {\n const includeGitignore = which ? which.includes(\"gitignore\") : true;\n const templateTargets = which\n ? templatesByName(which.filter((c): c is ConfigName => c !== \"gitignore\"))\n : ALL_TEMPLATES;\n\n const lines: string[] = [];\n for (const t of templateTargets) {\n let existing = \"\";\n try {\n existing = await readFile(join(cwd, t.path), \"utf-8\");\n } catch {\n // missing file => will be created\n }\n if (existing !== t.contents) lines.push(`would update ${t.path} (config: ${t.config})`);\n }\n if (includeGitignore) {\n const gi = await dryPlanGitignore(cwd);\n if (gi) lines.push(gi);\n }\n return lines.length === 0 ? \"no changes needed\" : lines.join(\"\\n\");\n}\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"all configs in sync\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runSyncConfigsCommand(\n site: string | undefined,\n opts: SyncConfigsCommandOptions,\n): Promise<{ output: string; code: number }> {\n const which = parseOnly(opts.only);\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n if (opts.dry) {\n const blocks: string[] = [];\n for (const s of sites) {\n blocks.push(`[${s.name || s.path}]\\n` + (await dryPlan(s.path, which)));\n }\n return { output: appendSkipNotice(blocks.join(\"\\n\\n\"), skipped), code: 0 };\n }\n\n const results = await runRecipeOverSites(\"sync-configs\", sites, (s) =>\n syncConfigs(s, which ? { which } : {}),\n );\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,6 @@
1
+ import {
2
+ runRecipeOverSites
3
+ } from "./chunk-VPJ7N6P7.js";
1
4
  import {
2
5
  appendSkipNotice,
3
6
  fleetWorkdir,
@@ -5,11 +8,11 @@ import {
5
8
  } from "./chunk-4NAOR44V.js";
6
9
  import {
7
10
  resolveSites
8
- } from "./chunk-FH7WQHD7.js";
11
+ } from "./chunk-VUKSRWRD.js";
9
12
  import {
10
13
  upgradeSvelte4to5
11
- } from "./chunk-O65I7G7G.js";
12
- import "./chunk-OQPMZ6BM.js";
14
+ } from "./chunk-ZO7WNY57.js";
15
+ import "./chunk-J7SZQUCW.js";
13
16
  import "./chunk-XKOZUVK2.js";
14
17
  import "./chunk-OTGB6YQO.js";
15
18
  import "./chunk-FDIFTIXC.js";
@@ -48,12 +51,7 @@ async function runUpgradeCommand(upgradeName, site, opts = {}) {
48
51
  sites = prep.prepared;
49
52
  skipped = prep.skipped;
50
53
  }
51
- const results = [];
52
- for (const s of sites) {
53
- if (upgradeName === "svelte-4-to-5") {
54
- results.push(await upgradeSvelte4to5(s));
55
- }
56
- }
54
+ const results = await runRecipeOverSites("svelte-4-to-5", sites, (s) => upgradeSvelte4to5(s));
57
55
  const output = results.map(formatResult).join("\n");
58
56
  const code = results.some((r) => r.status === "failed") ? 1 : 0;
59
57
  return { output: appendSkipNotice(output, skipped), code };
@@ -61,4 +59,4 @@ async function runUpgradeCommand(upgradeName, site, opts = {}) {
61
59
  export {
62
60
  runUpgradeCommand
63
61
  };
64
- //# sourceMappingURL=upgrade-UBPPJ6HN.js.map
62
+ //# sourceMappingURL=upgrade-7TN2XPFK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/upgrade.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { upgradeSvelte4to5 } from \"../../recipes/svelte-5/index.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { runRecipeOverSites } from \"../fleet/run-recipe-over-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nconst KNOWN_UPGRADES = new Set([\"svelte-4-to-5\"]);\n\nexport type UpgradeCommandOptions = {\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runUpgradeCommand(\n upgradeName: string | undefined,\n site: string | undefined,\n opts: UpgradeCommandOptions = {},\n): Promise<{ output: string; code: number }> {\n if (!upgradeName || !KNOWN_UPGRADES.has(upgradeName)) {\n throw Object.assign(\n new Error(\n `unknown upgrade: ${upgradeName ?? \"(none)\"}. expected one of ${[...KNOWN_UPGRADES].join(\", \")}`,\n ),\n { exitCode: 2 },\n );\n }\n\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n // `upgradeName` is validated against KNOWN_UPGRADES above (throws otherwise),\n // so the only reachable upgrade here is the svelte-4-to-5 recipe.\n const results = await runRecipeOverSites(\"svelte-4-to-5\", sites, (s) => upgradeSvelte4to5(s));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAQxB,IAAM,iBAAiB,oBAAI,IAAI,CAAC,eAAe,CAAC;AAQhD,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,kBACpB,aACA,MACA,OAA8B,CAAC,GACY;AAC3C,MAAI,CAAC,eAAe,CAAC,eAAe,IAAI,WAAW,GAAG;AACpD,UAAM,OAAO;AAAA,MACX,IAAI;AAAA,QACF,oBAAoB,eAAe,QAAQ,qBAAqB,CAAC,GAAG,cAAc,EAAE,KAAK,IAAI,CAAC;AAAA,MAChG;AAAA,MACA,EAAE,UAAU,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAIA,QAAM,UAAU,MAAM,mBAAmB,iBAAiB,OAAO,CAAC,MAAM,kBAAkB,CAAC,CAAC;AAE5F,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}
@@ -20,7 +20,7 @@ import {
20
20
  updateScores,
21
21
  updateSecurityCounts,
22
22
  updateSiteField
23
- } from "./chunk-7RGQ4KLE.js";
23
+ } from "./chunk-CCXVX5JN.js";
24
24
  export {
25
25
  ACTIVE_STATUSES,
26
26
  SEVERITY_RANK,
@@ -44,4 +44,4 @@ export {
44
44
  updateSecurityCounts,
45
45
  updateSiteField
46
46
  };
47
- //# sourceMappingURL=websites-CSVLSEVL.js.map
47
+ //# sourceMappingURL=websites-EIPNY4DY.js.map
@@ -2,13 +2,13 @@ import {
2
2
  formatFleetWriteSummary,
3
3
  writeAuditsToAirtable,
4
4
  writeFleetAuditsToAirtable
5
- } from "./chunk-LM42CATB.js";
6
- import "./chunk-CSTLFSGM.js";
5
+ } from "./chunk-MEP6PR32.js";
6
+ import "./chunk-N5MZ6WRX.js";
7
7
  import "./chunk-5L3FPQIJ.js";
8
- import "./chunk-7RGQ4KLE.js";
8
+ import "./chunk-CCXVX5JN.js";
9
9
  export {
10
10
  formatFleetWriteSummary,
11
11
  writeAuditsToAirtable,
12
12
  writeFleetAuditsToAirtable
13
13
  };
14
- //# sourceMappingURL=write-audits-to-airtable-JCV7FYAW.js.map
14
+ //# sourceMappingURL=write-audits-to-airtable-WVWFESZW.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reddoorla/maintenance",
3
- "version": "0.65.0",
3
+ "version": "0.65.3",
4
4
  "description": "Canonical maintenance configs, audits, and recipes for the reddoor stack.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,9 +0,0 @@
1
- import {
2
- fromAirtableBase
3
- } from "./chunk-MQM5YP4J.js";
4
- import "./chunk-U5SZ4FOP.js";
5
- import "./chunk-7RGQ4KLE.js";
6
- export {
7
- fromAirtableBase
8
- };
9
- //# sourceMappingURL=airtable-GGZJUGQB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/recipes/announce.ts","../src/cli/commands/announce.ts"],"sourcesContent":["import { openBase, readAirtableConfig } from \"../reports/airtable/client.js\";\nimport type { AirtableBase } from \"../reports/airtable/client.js\";\nimport { listWebsites, siteSlug } from \"../reports/airtable/websites.js\";\nimport type { WebsiteRow } from \"../reports/airtable/websites.js\";\nimport {\n createDraft,\n findReportByPeriod,\n updateReportScores,\n type ReportEnrichment,\n} from \"../reports/airtable/reports.js\";\nimport { queueDraft } from \"../reports/queue.js\";\nimport { uploadAttachment } from \"../reports/airtable/attachments.js\";\nimport { renderReportHtml } from \"../reports/render.js\";\nimport { resolveCopy } from \"../reports/copy.js\";\nimport { fetchGaUsers, fetchSearch } from \"../reports/draft.js\";\nimport { announcementSiteExtras } from \"../reports/announcement-email/template.js\";\nimport type { LighthouseScores } from \"../reports/types.js\";\nimport { defaultReportSubject } from \"../reports/subject.js\";\nimport { scoresFromRow } from \"../reports/report-data.js\";\n\nexport type AnnounceSiteResult =\n | {\n site: string;\n status: \"drafted\" | \"reused\";\n reportId: string;\n recipientMissing: boolean;\n /** False when a higher-or-equal-tier report was already queued (single-queue rule). */\n queued: boolean;\n }\n | { site: string; status: \"skipped-no-scores\" }\n | { site: string; status: \"error\"; message: string };\n\nexport type AnnounceResult = { results: AnnounceSiteResult[] };\n\n/** The traffic/search lookback window (days) the announcement reports on. The trend compares it\n * against the equal-length prior window, and the email labels it \"vs the previous N days\". */\nconst GA_WINDOW_DAYS = 30;\n\nexport type AnnounceDeps = {\n /** Airtable handle. Defaults to opening the live base from credentials. */\n base?: AirtableBase;\n /** When set, restrict to the single site whose slug matches. Default: all maintenance sites. */\n site?: string;\n /** Single timestamp driving the period key, render, draft, and preview filename. */\n now?: Date;\n};\n\n/**\n * Draft the monthly-report ANNOUNCEMENT email for every `maintenance` site (or one,\n * via `deps.site`). Airtable-driven and fleet-wide: unlike `launch`, it runs no audits\n * and takes no `Site`/inventory object — it reads the Lighthouse scores already stored\n * on each Websites row. DRAFTS ONLY; the M3 approve loop sends.\n *\n * One bad site must never abort the run: each site is wrapped in its own try/catch that\n * records an `error` result and continues.\n */\nexport async function announce(deps?: AnnounceDeps): Promise<AnnounceResult> {\n const base = deps?.base ?? openBase(readAirtableConfig());\n const now = deps?.now ?? new Date();\n\n const websites = await listWebsites(base);\n let targets = websites.filter((w) => w.status === \"maintenance\");\n if (deps?.site) {\n const wanted = siteSlug(deps.site);\n targets = targets.filter((w) => siteSlug(w.name) === wanted);\n }\n\n const period = now.toISOString().slice(0, 7);\n const results: AnnounceSiteResult[] = [];\n\n for (const w of targets) {\n try {\n const scores = scoresFromRow(w);\n if (scores === null) {\n results.push({ site: w.name, status: \"skipped-no-scores\" });\n continue;\n }\n\n // Traffic + search snapshot over a ~30-day window ending now (fetchPeriodUsers derives\n // the equal-length previous window for the trend). Reuses the report pipeline's\n // soft-failing enrichment: GA/search unconfigured or an API error leaves the numbers\n // null and the email simply omits the traffic section — it never blocks the draft.\n const periodEnd = now;\n const periodStart = new Date(now.getTime() - GA_WINDOW_DAYS * 24 * 60 * 60 * 1000);\n const gaUsers = (await fetchGaUsers(w, periodStart, periodEnd)).value;\n const search = (await fetchSearch(w, periodStart, periodEnd)).value;\n const enrichment: ReportEnrichment = {\n ...(gaUsers ? { gaUsersCurrent: gaUsers.current, gaUsersPrevious: gaUsers.previous } : {}),\n ...(search ? { searchFoundPage1: search.foundOnPage1 } : {}),\n ...(search?.foundOnPage1 && search.position !== null\n ? { searchPosition: search.position }\n : {}),\n };\n\n // Dedupe: reuse an existing Announcement row for this (site, period) rather than\n // stacking a second draft. The reuse path refreshes the stored scores + traffic/search\n // (and Completed on) so the eventually-sent email — which reads the row — isn't stale.\n // The create path writes them via createDraft.\n let report;\n let statusKind: \"drafted\" | \"reused\";\n const existing = await findReportByPeriod(base, w.id, \"Announcement\", period);\n if (existing) {\n await updateReportScores(base, existing.id, scores, now, enrichment);\n report = existing;\n statusKind = \"reused\";\n } else {\n report = await createDraft(base, draftInputFor(w, scores, now, period, enrichment));\n statusKind = \"drafted\";\n }\n\n const slug = siteSlug(w.name);\n const { html } = await renderReportHtml({\n siteName: w.name,\n siteUrl: w.url,\n reportType: \"Announcement\",\n completedOn: now,\n lighthouse: scores,\n gaUsersCurrent: gaUsers?.current,\n gaUsersPrevious: gaUsers?.previous,\n gaPeriodDays: GA_WINDOW_DAYS,\n searchPosition: search?.foundOnPage1 ? (search.position ?? undefined) : undefined,\n lastTestedDate: null,\n commentary: null,\n copy: resolveCopy(w),\n headerImageCid: `${slug}-header`,\n // cadence (the client's go-forward pace, \"None\" omitted) + default-on improvement\n // callouts. Shared with the send re-render via announcementSiteExtras so the sent\n // email matches this reviewed preview.\n ...announcementSiteExtras(w),\n });\n\n // A preview-upload hiccup must NOT fail the site — log and continue.\n try {\n await uploadAttachment(\n report.id,\n \"Rendered HTML\",\n html,\n `${slug}-${now.toISOString().slice(0, 10)}.html`,\n \"text/html\",\n );\n } catch (uploadErr) {\n console.warn(\n `⚠ Announcement preview upload skipped for ${w.name}: ${\n uploadErr instanceof Error ? uploadErr.message : String(uploadErr)\n }`,\n );\n }\n\n // Critical: NOT wrapped — without queueing, the draft never enters the approve queue,\n // so a failure here must surface as an error result for the site. queueDraft also\n // supersedes any lower-tier (Maintenance/Testing) drafts queued for this site, and\n // stands down if an equal-or-higher report is already queued (single-queue rule).\n const queue = await queueDraft(base, {\n id: report.id,\n siteId: w.id,\n reportType: \"Announcement\",\n });\n\n const recipientMissing = !(w.reportRecipientsTo && w.reportRecipientsTo.trim());\n results.push({\n site: w.name,\n status: statusKind,\n reportId: report.id,\n recipientMissing,\n queued: queue.queued,\n });\n } catch (err) {\n results.push({\n site: w.name,\n status: \"error\",\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { results };\n}\n\n/** Build the Announcement `DraftInput`. Announcements have no period window and no prior\n * maintenance test, so periodStart/periodEnd/completedOn all collapse to `now` and\n * `lastTestedDate` is null. The subject override gives the email a purpose-built line. */\nfunction draftInputFor(\n w: WebsiteRow,\n scores: LighthouseScores,\n now: Date,\n period: string,\n enrichment: ReportEnrichment,\n): Parameters<typeof createDraft>[1] {\n return {\n reportId: `${w.name} — Announcement — ${now.toISOString().slice(0, 10)}`,\n siteId: w.id,\n reportType: \"Announcement\",\n period,\n periodStart: now,\n periodEnd: now,\n completedOn: now,\n lighthouse: scores,\n lastTestedDate: null,\n subjectOverride: defaultReportSubject({\n name: w.name,\n url: w.url,\n type: \"Announcement\",\n date: now,\n }),\n ...enrichment,\n };\n}\n","import { announce, type AnnounceResult, type AnnounceSiteResult } from \"../../recipes/announce.js\";\n\nexport type AnnounceCommandOptions = {\n cwd?: string;\n};\n\nfunction formatSiteResult(r: AnnounceSiteResult): string {\n if (r.status === \"skipped-no-scores\") return `[${r.site}] skipped-no-scores`;\n if (r.status === \"error\") return `[${r.site}] error: ${r.message}`;\n const note = r.recipientMissing ? \" ⚠ recipient missing\" : \"\";\n return `[${r.site}] ${r.status}${note}`;\n}\n\nexport function formatAnnounceResult(result: AnnounceResult): string {\n if (result.results.length === 0) return \"No maintenance sites to announce.\";\n return result.results.map(formatSiteResult).join(\"\\n\");\n}\n\n/**\n * `announce [site]` — Airtable-driven and fleet-wide. Draft the monthly-report\n * announcement email for every `maintenance` site (or one, when `site` is given) into\n * the M3 approve queue. Never sends; the operator approves each draft and the next send\n * run delivers it. Reads the Lighthouse scores already stored on each Websites row —\n * no audits are run.\n */\nexport async function runAnnounceCommand(\n site: string | undefined,\n _opts: AnnounceCommandOptions,\n): Promise<{ output: string; code: number }> {\n const result = await announce(site ? { site } : {});\n const hadError = result.results.some((r) => r.status === \"error\");\n return { output: formatAnnounceResult(result), code: hadError ? 1 : 0 };\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/commands/bump-deps.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { bumpDeps, type BumpDepsGroup } from \"../../recipes/bump-deps.js\";\nimport type { RecipeResult } from \"../../types.js\";\nimport { resolveSites } from \"../fleet/resolve-sites.js\";\nimport { prepareFleetSites, appendSkipNotice, type SkippedSite } from \"../fleet/prepare-sites.js\";\nimport { fleetWorkdir } from \"../../util/fleet-workdir.js\";\n\nconst GROUPS: BumpDepsGroup[] = [\"patch\", \"minor\", \"major\"];\n\nexport type BumpDepsCommandOptions = {\n group?: string;\n fleet?: string;\n workdir?: string;\n cwd?: string;\n};\n\nfunction formatResult(r: RecipeResult): string {\n if (r.status === \"noop\") return `[${r.site}] noop: ${r.notes ?? \"\"}`;\n return `[${r.site}] applied: ${r.commits.length} commit(s)\\n${r.notes ?? \"\"}`;\n}\n\nexport async function runBumpDepsCommand(\n site: string | undefined,\n opts: BumpDepsCommandOptions,\n): Promise<{ output: string; code: number }> {\n const group = (opts.group ?? \"minor\") as BumpDepsGroup;\n if (!GROUPS.includes(group)) {\n throw Object.assign(\n new Error(`unknown --group: ${group}. expected one of ${GROUPS.join(\", \")}`),\n { exitCode: 2 },\n );\n }\n\n const cwd = opts.cwd ? resolve(opts.cwd) : process.cwd();\n\n let sites = await resolveSites({\n ...(site !== undefined ? { site } : {}),\n ...(opts.fleet !== undefined ? { fleet: opts.fleet } : {}),\n cwd,\n });\n\n let skipped: SkippedSite[] = [];\n if (opts.fleet) {\n const workdir = opts.workdir ?? fleetWorkdir();\n const prep = await prepareFleetSites(sites, { workdir });\n sites = prep.prepared;\n skipped = prep.skipped;\n }\n\n const results: RecipeResult[] = [];\n for (const s of sites) results.push(await bumpDeps(s, { group }));\n\n const output = results.map(formatResult).join(\"\\n\");\n const code = results.some((r) => r.status === \"failed\") ? 1 : 0;\n return { output: appendSkipNotice(output, skipped), code };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAe;AAOxB,IAAM,SAA0B,CAAC,SAAS,SAAS,OAAO;AAS1D,SAAS,aAAa,GAAyB;AAC7C,MAAI,EAAE,WAAW,OAAQ,QAAO,IAAI,EAAE,IAAI,WAAW,EAAE,SAAS,EAAE;AAClE,SAAO,IAAI,EAAE,IAAI,cAAc,EAAE,QAAQ,MAAM;AAAA,EAAe,EAAE,SAAS,EAAE;AAC7E;AAEA,eAAsB,mBACpB,MACA,MAC2C;AAC3C,QAAM,QAAS,KAAK,SAAS;AAC7B,MAAI,CAAC,OAAO,SAAS,KAAK,GAAG;AAC3B,UAAM,OAAO;AAAA,MACX,IAAI,MAAM,oBAAoB,KAAK,qBAAqB,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,MAC3E,EAAE,UAAU,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,QAAQ,IAAI;AAEvD,MAAI,QAAQ,MAAM,aAAa;AAAA,IAC7B,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,IACxD;AAAA,EACF,CAAC;AAED,MAAI,UAAyB,CAAC;AAC9B,MAAI,KAAK,OAAO;AACd,UAAM,UAAU,KAAK,WAAW,aAAa;AAC7C,UAAM,OAAO,MAAM,kBAAkB,OAAO,EAAE,QAAQ,CAAC;AACvD,YAAQ,KAAK;AACb,cAAU,KAAK;AAAA,EACjB;AAEA,QAAM,UAA0B,CAAC;AACjC,aAAW,KAAK,MAAO,SAAQ,KAAK,MAAM,SAAS,GAAG,EAAE,MAAM,CAAC,CAAC;AAEhE,QAAM,SAAS,QAAQ,IAAI,YAAY,EAAE,KAAK,IAAI;AAClD,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AAC9D,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,OAAO,GAAG,KAAK;AAC3D;","names":[]}