@reddoorla/maintenance 0.65.0 → 0.65.1

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 (66) hide show
  1. package/README.md +17 -10
  2. package/dist/{announce-GFLKAPTT.js → announce-BRBITWUP.js} +23 -8
  3. package/dist/announce-BRBITWUP.js.map +1 -0
  4. package/dist/{bump-deps-3QQHYDKJ.js → bump-deps-4BODIOEF.js} +5 -3
  5. package/dist/bump-deps-4BODIOEF.js.map +1 -0
  6. package/dist/{chunk-UATHDNWP.js → chunk-IRRZG66U.js} +13 -6
  7. package/dist/chunk-IRRZG66U.js.map +1 -0
  8. package/dist/{chunk-U3MF6RCS.js → chunk-PBDZGBGL.js} +11 -7
  9. package/dist/chunk-PBDZGBGL.js.map +1 -0
  10. package/dist/{chunk-M5LX2VSR.js → chunk-SWSFB6IV.js} +2 -2
  11. package/dist/{chunk-FX3QBSUF.js → chunk-UCXZYS2W.js} +2 -2
  12. package/dist/chunk-VPJ7N6P7.js +27 -0
  13. package/dist/chunk-VPJ7N6P7.js.map +1 -0
  14. package/dist/{chunk-TC7Z5LG7.js → chunk-WCN54744.js} +30 -16
  15. package/dist/{chunk-TC7Z5LG7.js.map → chunk-WCN54744.js.map} +1 -1
  16. package/dist/{chunk-OYN6H4CX.js → chunk-XGT3I5AK.js} +3 -3
  17. package/dist/{chunk-QSL3EJGI.js → chunk-XUKSP67U.js} +2 -2
  18. package/dist/{chunk-4GACMVNE.js → chunk-YEGHUODU.js} +17 -1
  19. package/dist/chunk-YEGHUODU.js.map +1 -0
  20. package/dist/cli/bin.js +14 -14
  21. package/dist/cli/commands/audit.js +2 -2
  22. package/dist/{convert-to-pnpm-ZO673UFB.js → convert-to-pnpm-S4TNJD53.js} +5 -3
  23. package/dist/convert-to-pnpm-S4TNJD53.js.map +1 -0
  24. package/dist/{github-signals-N5JGWHW2.js → github-signals-R4FNU34K.js} +2 -2
  25. package/dist/index.d.ts +25 -7
  26. package/dist/index.js +6 -6
  27. package/dist/{init-FOHNISF2.js → init-GLT5C6S5.js} +23 -6
  28. package/dist/init-GLT5C6S5.js.map +1 -0
  29. package/dist/{launch-TM3IHSSU.js → launch-CQM5D6QJ.js} +5 -5
  30. package/dist/{onboard-K2EL4MSG.js → onboard-ILC3DWY4.js} +9 -5
  31. package/dist/onboard-ILC3DWY4.js.map +1 -0
  32. package/dist/{orchestrate-OX3Z4DUI.js → orchestrate-45URUFEK.js} +3 -3
  33. package/dist/{renovate-dispatch-H25CQ36P.js → renovate-dispatch-G4T73IUR.js} +2 -2
  34. package/dist/{report-UEYKO6WH.js → report-BZ6QNFNM.js} +4 -4
  35. package/dist/{self-updating-YXOGQWH5.js → self-updating-DEZNP5OK.js} +7 -5
  36. package/dist/self-updating-DEZNP5OK.js.map +1 -0
  37. package/dist/{selftest-VE7CSGWE.js → selftest-TY7X5ARI.js} +5 -5
  38. package/dist/{svelte-codemods-745QM25J.js → svelte-codemods-DMLMOKSD.js} +5 -3
  39. package/dist/svelte-codemods-DMLMOKSD.js.map +1 -0
  40. package/dist/{sync-configs-NYC3Z625.js → sync-configs-DWKXETFO.js} +9 -3
  41. package/dist/sync-configs-DWKXETFO.js.map +1 -0
  42. package/dist/{upgrade-UBPPJ6HN.js → upgrade-RUX2ODMW.js} +5 -7
  43. package/dist/upgrade-RUX2ODMW.js.map +1 -0
  44. package/package.json +1 -1
  45. package/dist/announce-GFLKAPTT.js.map +0 -1
  46. package/dist/bump-deps-3QQHYDKJ.js.map +0 -1
  47. package/dist/chunk-4GACMVNE.js.map +0 -1
  48. package/dist/chunk-U3MF6RCS.js.map +0 -1
  49. package/dist/chunk-UATHDNWP.js.map +0 -1
  50. package/dist/convert-to-pnpm-ZO673UFB.js.map +0 -1
  51. package/dist/init-FOHNISF2.js.map +0 -1
  52. package/dist/onboard-K2EL4MSG.js.map +0 -1
  53. package/dist/self-updating-YXOGQWH5.js.map +0 -1
  54. package/dist/svelte-codemods-745QM25J.js.map +0 -1
  55. package/dist/sync-configs-NYC3Z625.js.map +0 -1
  56. package/dist/upgrade-UBPPJ6HN.js.map +0 -1
  57. /package/dist/{chunk-M5LX2VSR.js.map → chunk-SWSFB6IV.js.map} +0 -0
  58. /package/dist/{chunk-FX3QBSUF.js.map → chunk-UCXZYS2W.js.map} +0 -0
  59. /package/dist/{chunk-OYN6H4CX.js.map → chunk-XGT3I5AK.js.map} +0 -0
  60. /package/dist/{chunk-QSL3EJGI.js.map → chunk-XUKSP67U.js.map} +0 -0
  61. /package/dist/{github-signals-N5JGWHW2.js.map → github-signals-R4FNU34K.js.map} +0 -0
  62. /package/dist/{launch-TM3IHSSU.js.map → launch-CQM5D6QJ.js.map} +0 -0
  63. /package/dist/{orchestrate-OX3Z4DUI.js.map → orchestrate-45URUFEK.js.map} +0 -0
  64. /package/dist/{renovate-dispatch-H25CQ36P.js.map → renovate-dispatch-G4T73IUR.js.map} +0 -0
  65. /package/dist/{report-UEYKO6WH.js.map → report-BZ6QNFNM.js.map} +0 -0
  66. /package/dist/{selftest-VE7CSGWE.js.map → selftest-TY7X5ARI.js.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  fetchGaUsers,
3
3
  fetchSearch
4
- } from "./chunk-M5LX2VSR.js";
4
+ } from "./chunk-SWSFB6IV.js";
5
5
  import {
6
6
  announcementSiteExtras,
7
7
  resolveCopy
8
- } from "./chunk-U3MF6RCS.js";
8
+ } from "./chunk-PBDZGBGL.js";
9
9
  import {
10
10
  siteSlug
11
11
  } from "./chunk-7RGQ4KLE.js";
@@ -60,4 +60,4 @@ export {
60
60
  scoresFromRow,
61
61
  buildReportDataForSite
62
62
  };
63
- //# sourceMappingURL=chunk-OYN6H4CX.js.map
63
+ //# sourceMappingURL=chunk-XGT3I5AK.js.map
@@ -10,7 +10,7 @@ import {
10
10
  loadBundledImages,
11
11
  renderReportHtml,
12
12
  resolveCopy
13
- } from "./chunk-U3MF6RCS.js";
13
+ } from "./chunk-PBDZGBGL.js";
14
14
  import {
15
15
  checklistFor,
16
16
  isChecklistComplete,
@@ -303,4 +303,4 @@ export {
303
303
  parseAddresses,
304
304
  isProbablyEmail
305
305
  };
306
- //# sourceMappingURL=chunk-QSL3EJGI.js.map
306
+ //# sourceMappingURL=chunk-XUKSP67U.js.map
@@ -106,6 +106,22 @@ function makeGitHub(deps) {
106
106
  }
107
107
  return present;
108
108
  },
109
+ async fileContentsOnBranch(repo, branch, path) {
110
+ assertUrlSegment("branch", branch);
111
+ assertUrlSegment("path", path);
112
+ const r = await spawn(
113
+ "gh",
114
+ [
115
+ "api",
116
+ `repos/${repo}/contents/${path}?ref=${branch}`,
117
+ "-H",
118
+ "Accept: application/vnd.github.raw"
119
+ ],
120
+ { env, timeoutMs: 6e4 }
121
+ );
122
+ if (r.code !== 0) return null;
123
+ return r.stdout;
124
+ },
109
125
  async branchProtectionContexts(repo, branch) {
110
126
  assertUrlSegment("branch", branch);
111
127
  const r = await spawn(
@@ -239,4 +255,4 @@ export {
239
255
  assertUrlSegment,
240
256
  makeGitHub
241
257
  };
242
- //# sourceMappingURL=chunk-4GACMVNE.js.map
258
+ //# sourceMappingURL=chunk-YEGHUODU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/github/gh.ts"],"sourcesContent":["import { defaultSpawn, type SpawnFn } from \"../audits/util/spawn.js\";\n\n/** Aggregate CI state of a PR's head commit, normalized from GitHub's rollup. */\nexport type CiState = \"passing\" | \"failing\" | \"pending\" | \"none\";\n\n/** GitHub's computed mergeability of a PR. `UNKNOWN` is transient — GitHub is\n * still computing it (e.g. right after a push) — so it should be read as \"not\n * known to conflict\", never as conflicting. */\nexport type PrMergeable = \"MERGEABLE\" | \"CONFLICTING\" | \"UNKNOWN\";\n\n/** A minimal open-PR summary with its head-commit CI rollup state + mergeability. */\nexport type PullRequestSummary = {\n number: number;\n title: string;\n url: string;\n headRef: string;\n ciState: CiState;\n mergeable: PrMergeable;\n};\n\n/**\n * Reject a value before it's interpolated into a `gh api` URL path. The\n * `owner/repo` split methods already validate shape; this is the defense-in-depth\n * guard for the `branch` and file-`path` segments. An unexpected value (`..`, a\n * leading `/`, whitespace, or a URL-structural char like `?#%` or a backslash)\n * could otherwise retarget the endpoint (escape the intended path, smuggle a\n * query string, or traverse). Conservative by design — legit branch names like\n * `maint/self-updating-x` and paths like `.github/workflows/ci.yml` pass.\n *\n * Both branch refs (`maint/self-updating-x`) and file paths\n * (`.github/workflows/ci.yml`) legitimately contain `/`, so a single slash is\n * allowed; what's rejected is `..`, a leading `/`, whitespace, or a\n * URL-structural char (`?`, `#`, `%`, backslash) that could escape or retarget\n * the endpoint.\n */\nexport function assertUrlSegment(kind: \"branch\" | \"path\", value: string): void {\n const structural = /[\\s?#%\\\\]|\\.\\./;\n if (value.length === 0 || value.startsWith(\"/\") || structural.test(value)) {\n throw new Error(\n `unsafe ${kind} for gh api path (illegal characters or traversal): ${JSON.stringify(value)}`,\n );\n }\n}\n\n/** Map GitHub's `statusCheckRollup.state` enum to our normalized CiState. */\nfunction mapRollupState(state: string | null | undefined): CiState {\n switch (state) {\n case \"SUCCESS\":\n return \"passing\";\n case \"FAILURE\":\n case \"ERROR\":\n return \"failing\";\n case \"PENDING\":\n case \"EXPECTED\":\n return \"pending\";\n default:\n return \"none\"; // null/undefined = no checks reported\n }\n}\n\n/** Coerce GitHub's `mergeable` enum to our PrMergeable. Anything unexpected\n * (including the literal `UNKNOWN` GitHub returns while still computing) maps to\n * `UNKNOWN` — i.e. \"not known to conflict\". Only an explicit `CONFLICTING` is. */\nfunction mapMergeable(state: string | null | undefined): PrMergeable {\n return state === \"MERGEABLE\" || state === \"CONFLICTING\" ? state : \"UNKNOWN\";\n}\n\nexport type GitHub = {\n openPullRequest: (\n repo: string,\n pr: { head: string; base: string; title: string; body: string },\n ) => Promise<{ url: string }>;\n enableRepoAutoMerge: (repo: string) => Promise<void>;\n protectBranch: (repo: string, branch: string, requiredChecks: string[]) => Promise<void>;\n setRepoSecret: (repo: string, name: string, value: string) => Promise<void>;\n repoExists: (repo: string) => Promise<boolean>;\n defaultBranch: (repo: string) => Promise<string>;\n filesOnBranch: (repo: string, branch: string, paths: string[]) => Promise<string[]>;\n /** The raw contents of `path` on `branch`, or null when the file is absent (404).\n * Lets a caller detect a present-but-STALE file (content drift), where\n * `filesOnBranch` only sees existence. */\n fileContentsOnBranch: (repo: string, branch: string, path: string) => Promise<string | null>;\n branchProtectionContexts: (repo: string, branch: string) => Promise<string[]>;\n secretExists: (repo: string, name: string) => Promise<boolean>;\n autoMergeEnabled: (repo: string) => Promise<boolean>;\n findOpenSelfUpdatingPR: (repo: string) => Promise<string | null>;\n /** All open PRs on a repo with each head commit's normalized CI rollup state. */\n openPullRequests: (repo: string) => Promise<PullRequestSummary[]>;\n /** The default branch's latest-commit date + normalized CI rollup, one query. */\n defaultBranchStatus: (repo: string) => Promise<{ ciState: CiState; lastCommitAt: string | null }>;\n /** Renovate PRs (head `renovate/*`) merged at/after `sinceIso`. Used to record\n * `pr_automerged` fleet events. gh-shell (Actions only). */\n mergedRenovatePullRequests: (\n repo: string,\n sinceIso: string,\n ) => Promise<Array<{ number: number; title: string; url: string; mergedAt: string }>>;\n /** Fire a `workflow_dispatch` for `<workflow>` (a filename like `renovate.yml`)\n * on `ref`. Requires the token's `actions:write` scope; a 404 (no such\n * workflow) or 403 (missing scope) surfaces as a thrown error. */\n dispatchWorkflow: (repo: string, workflow: string, ref: string) => Promise<void>;\n};\n\nexport function makeGitHub(deps: { token: string; spawn?: SpawnFn }): GitHub {\n const spawn = deps.spawn ?? defaultSpawn;\n const env = { ...process.env, GH_TOKEN: deps.token };\n\n async function gh(args: string[]): Promise<string> {\n const r = await spawn(\"gh\", args, { env, timeoutMs: 60_000 });\n if (r.code !== 0) throw new Error(`gh ${args[0]} failed (code ${r.code}): ${r.stderr.trim()}`);\n return r.stdout;\n }\n\n return {\n async openPullRequest(repo, pr) {\n const out = await gh([\n \"pr\",\n \"create\",\n \"--repo\",\n repo,\n \"--head\",\n pr.head,\n \"--base\",\n pr.base,\n \"--title\",\n pr.title,\n \"--body\",\n pr.body,\n ]);\n return { url: out.trim() };\n },\n async enableRepoAutoMerge(repo) {\n await gh([\"api\", \"-X\", \"PATCH\", `repos/${repo}`, \"-F\", \"allow_auto_merge=true\"]);\n },\n async protectBranch(repo, branch, requiredChecks) {\n assertUrlSegment(\"branch\", branch);\n const args = [\n \"api\",\n \"-X\",\n \"PUT\",\n `repos/${repo}/branches/${branch}/protection`,\n \"-H\",\n \"Accept: application/vnd.github+json\",\n \"-F\",\n \"required_status_checks[strict]=true\",\n ...requiredChecks.flatMap((c) => [\"-f\", `required_status_checks[contexts][]=${c}`]),\n \"-F\",\n \"enforce_admins=true\",\n \"-F\",\n \"required_pull_request_reviews=null\",\n \"-F\",\n \"restrictions=null\",\n ];\n await gh(args);\n },\n async setRepoSecret(repo, name, value) {\n await gh([\"secret\", \"set\", name, \"--repo\", repo, \"--body\", value]);\n },\n async repoExists(repo) {\n const r = await spawn(\"gh\", [\"api\", `repos/${repo}`], { env, timeoutMs: 60_000 });\n return r.code === 0;\n },\n async defaultBranch(repo) {\n const out = await gh([\"api\", `repos/${repo}`, \"--jq\", \".default_branch\"]);\n return out.trim();\n },\n // filesOnBranch and branchProtectionContexts call `spawn` directly (not the\n // throwing `gh()` helper) because a 404 is an expected, meaningful answer —\n // \"file/protection absent\" — not an error. The remaining readers use `gh()`\n // since a non-200 there is a genuine failure (e.g. missing token scope).\n async filesOnBranch(repo, branch, paths) {\n assertUrlSegment(\"branch\", branch);\n const present: string[] = [];\n for (const p of paths) {\n assertUrlSegment(\"path\", p);\n const r = await spawn(\"gh\", [`api`, `repos/${repo}/contents/${p}?ref=${branch}`], {\n env,\n timeoutMs: 60_000,\n });\n if (r.code === 0) present.push(p);\n }\n return present;\n },\n async fileContentsOnBranch(repo, branch, path) {\n // Same spawn-directly rationale as filesOnBranch: a 404 (file absent) is an\n // expected answer (null), not an error. The `raw` media type returns the file\n // bytes verbatim (no base64 envelope) so the result compares directly against a\n // canonical template.\n assertUrlSegment(\"branch\", branch);\n assertUrlSegment(\"path\", path);\n const r = await spawn(\n \"gh\",\n [\n \"api\",\n `repos/${repo}/contents/${path}?ref=${branch}`,\n \"-H\",\n \"Accept: application/vnd.github.raw\",\n ],\n { env, timeoutMs: 60_000 },\n );\n if (r.code !== 0) return null; // 404 = file absent on this branch\n return r.stdout;\n },\n async branchProtectionContexts(repo, branch) {\n assertUrlSegment(\"branch\", branch);\n const r = await spawn(\n \"gh\",\n [\n \"api\",\n `repos/${repo}/branches/${branch}/protection`,\n \"--jq\",\n \".required_status_checks.contexts[]?\",\n ],\n { env, timeoutMs: 60_000 },\n );\n if (r.code !== 0) return []; // 404 = no protection configured\n return r.stdout\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0);\n },\n async secretExists(repo, name) {\n // per_page=100: the REST default of 30 would false-negative on a repo with >30 secrets,\n // wrongly reporting an existing secret absent (→ a needless overwrite).\n const out = await gh([\n \"api\",\n `repos/${repo}/actions/secrets?per_page=100`,\n \"--jq\",\n \".secrets[].name\",\n ]);\n return out\n .split(\"\\n\")\n .map((l) => l.trim())\n .includes(name);\n },\n async autoMergeEnabled(repo) {\n const out = await gh([\"api\", `repos/${repo}`, \"--jq\", \".allow_auto_merge\"]);\n return out.trim() === \"true\";\n },\n async findOpenSelfUpdatingPR(repo) {\n // per_page=100: with the REST default of 30, a repo with >30 open PRs (plausible under\n // Renovate) could page past the existing self-updating PR and open a duplicate.\n const out = await gh([\n \"api\",\n `repos/${repo}/pulls?state=open&per_page=100`,\n \"--jq\",\n '.[] | select(.head.ref | startswith(\"maint/self-updating-\")) | .html_url',\n ]);\n const first = out\n .split(\"\\n\")\n .map((l) => l.trim())\n .find((l) => l.length > 0);\n return first ?? null;\n },\n async openPullRequests(repo) {\n const [owner, name, ...rest] = repo.split(\"/\");\n if (!owner || !name || rest.length > 0) {\n throw new Error(`openPullRequests: expected \"owner/repo\", got \"${repo}\"`);\n }\n const query =\n \"query($owner:String!,$name:String!){repository(owner:$owner,name:$name){\" +\n \"pullRequests(states:OPEN,first:100,orderBy:{field:CREATED_AT,direction:DESC}){nodes{number title url headRefName mergeable \" +\n \"commits(last:1){nodes{commit{statusCheckRollup{state}}}}}}}}\";\n const out = await gh([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `name=${name}`,\n ]);\n const parsed = JSON.parse(out) as {\n data?: {\n repository?: {\n pullRequests?: {\n nodes?: Array<{\n number: number;\n title: string;\n url: string;\n headRefName: string;\n mergeable?: string;\n commits?: {\n nodes?: Array<{ commit?: { statusCheckRollup?: { state?: string } } }>;\n };\n }>;\n };\n };\n };\n };\n const nodes = parsed.data?.repository?.pullRequests?.nodes ?? [];\n return nodes.map((n) => ({\n number: n.number,\n title: n.title,\n url: n.url,\n headRef: n.headRefName,\n ciState: mapRollupState(n.commits?.nodes?.[0]?.commit?.statusCheckRollup?.state),\n mergeable: mapMergeable(n.mergeable),\n }));\n },\n async defaultBranchStatus(repo) {\n const [owner, name, ...rest] = repo.split(\"/\");\n if (!owner || !name || rest.length > 0) {\n throw new Error(`defaultBranchStatus: expected \"owner/repo\", got \"${repo}\"`);\n }\n const query =\n \"query($owner:String!,$name:String!){repository(owner:$owner,name:$name){\" +\n \"defaultBranchRef{target{... on Commit{committedDate statusCheckRollup{state}}}}}}\";\n const out = await gh([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `name=${name}`,\n ]);\n const parsed = JSON.parse(out) as {\n data?: {\n repository?: {\n defaultBranchRef?: {\n target?: { committedDate?: string; statusCheckRollup?: { state?: string } | null };\n } | null;\n };\n };\n };\n const target = parsed.data?.repository?.defaultBranchRef?.target;\n return {\n ciState: mapRollupState(target?.statusCheckRollup?.state),\n lastCommitAt: target?.committedDate ?? null,\n };\n },\n async mergedRenovatePullRequests(repo, sinceIso) {\n const [owner, name, ...rest] = repo.split(\"/\");\n if (!owner || !name || rest.length > 0) {\n throw new Error(`mergedRenovatePullRequests: expected \"owner/repo\", got \"${repo}\"`);\n }\n // per_page=50: comfortably covers a week of Renovate merges on one repo. The\n // list endpoint returns merged_at + head.ref, so the filter is local.\n const out = await gh([\n \"api\",\n `repos/${owner}/${name}/pulls?state=closed&sort=updated&direction=desc&per_page=50`,\n ]);\n const arr = JSON.parse(out) as Array<{\n number: number;\n title: string;\n html_url: string;\n merged_at: string | null;\n head?: { ref?: string };\n }>;\n return arr\n .filter(\n (p) =>\n p.merged_at !== null &&\n p.merged_at >= sinceIso && // ISO8601 UTC strings sort lexicographically\n (p.head?.ref ?? \"\").startsWith(\"renovate/\"),\n )\n .map((p) => ({\n number: p.number,\n title: p.title,\n url: p.html_url,\n mergedAt: p.merged_at as string,\n }));\n },\n async dispatchWorkflow(repo, workflow, ref) {\n const [owner, name, ...rest] = repo.split(\"/\");\n if (!owner || !name || rest.length > 0) {\n throw new Error(`dispatchWorkflow: expected \"owner/repo\", got \"${repo}\"`);\n }\n // Every segment interpolates into the API path, so guard them all like the\n // other write methods do (defense in depth). `owner`/`name` are the most\n // operator-controlled (typed into Airtable's \"Git repo\"); `workflow` is a\n // constant today; `ref` is repo-sourced. A junk value like `repo?x=1` would\n // otherwise smuggle a query string past the bare two-part shape check.\n assertUrlSegment(\"path\", owner);\n assertUrlSegment(\"path\", name);\n assertUrlSegment(\"path\", workflow);\n assertUrlSegment(\"branch\", ref);\n await gh([\n \"api\",\n \"-X\",\n \"POST\",\n `repos/${owner}/${name}/actions/workflows/${workflow}/dispatches`,\n \"-f\",\n `ref=${ref}`,\n ]);\n },\n };\n}\n"],"mappings":"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","names":[]}
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-NYC3Z625.js")).runSyncConfigsCommand(site, opts),
108
+ async () => (await import("../sync-configs-DWKXETFO.js")).runSyncConfigsCommand(site, opts),
109
109
  opts
110
110
  )
111
111
  );
@@ -114,7 +114,7 @@ cli.command("bump-deps [site]", "Bump dependencies.").option("--group <group>",
114
114
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
115
115
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
116
116
  async (site, opts) => runOrExit(
117
- async () => (await import("../bump-deps-3QQHYDKJ.js")).runBumpDepsCommand(site, opts),
117
+ async () => (await import("../bump-deps-4BODIOEF.js")).runBumpDepsCommand(site, opts),
118
118
  opts
119
119
  )
120
120
  );
@@ -123,7 +123,7 @@ cli.command(
123
123
  "Bootstrap a repo to keep itself updated (CI + Renovate + auto-merge)."
124
124
  ).option("--dry", "List what would be enabled without writing or opening PRs").option("--fleet <inventory>", 'Inventory file (.json or .mjs/.js), or "airtable"').option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
125
125
  async (site, opts) => runOrExit(
126
- async () => (await import("../self-updating-YXOGQWH5.js")).runSelfUpdatingCommand(site, opts),
126
+ async () => (await import("../self-updating-DEZNP5OK.js")).runSelfUpdatingCommand(site, opts),
127
127
  opts
128
128
  )
129
129
  );
@@ -132,7 +132,7 @@ cli.command("upgrade <upgrade> [site]", "Run a named upgrade recipe (svelte-4-to
132
132
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
133
133
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
134
134
  async (upgrade, site, opts) => runOrExit(
135
- async () => (await import("../upgrade-UBPPJ6HN.js")).runUpgradeCommand(upgrade, site, opts),
135
+ async () => (await import("../upgrade-RUX2ODMW.js")).runUpgradeCommand(upgrade, site, opts),
136
136
  opts
137
137
  )
138
138
  );
@@ -144,7 +144,7 @@ cli.command(
144
144
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
145
145
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
146
146
  async (site, opts) => runOrExit(
147
- async () => (await import("../convert-to-pnpm-ZO673UFB.js")).runConvertToPnpmCommand(site, opts),
147
+ async () => (await import("../convert-to-pnpm-S4TNJD53.js")).runConvertToPnpmCommand(site, opts),
148
148
  opts
149
149
  )
150
150
  );
@@ -153,7 +153,7 @@ cli.command("svelte-codemods [site]", "Apply Svelte 5 gotcha codemods to an alre
153
153
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
154
154
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
155
155
  async (site, opts) => runOrExit(
156
- async () => (await import("../svelte-codemods-745QM25J.js")).runSvelteCodemodsCommand(site, opts),
156
+ async () => (await import("../svelte-codemods-DMLMOKSD.js")).runSvelteCodemodsCommand(site, opts),
157
157
  opts
158
158
  )
159
159
  );
@@ -165,7 +165,7 @@ cli.command(
165
165
  'Inventory file (.json or .mjs/.js), or "airtable" to read from Websites table'
166
166
  ).option("--workdir <path>", "Clone target for fleet mode (default ~/.reddoor-maint/sites)").action(
167
167
  async (site, opts) => runOrExit(
168
- async () => (await import("../onboard-K2EL4MSG.js")).runOnboardCommand(site, opts),
168
+ async () => (await import("../onboard-ILC3DWY4.js")).runOnboardCommand(site, opts),
169
169
  opts
170
170
  )
171
171
  );
@@ -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-FOHNISF2.js")).runInitCommand(site, opts), opts)
179
+ async (site, opts) => runOrExit(async () => (await import("../init-GLT5C6S5.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-TM3IHSSU.js")).runLaunchCommand(site, opts),
186
+ async () => (await import("../launch-CQM5D6QJ.js")).runLaunchCommand(site, opts),
187
187
  opts
188
188
  )
189
189
  );
@@ -192,7 +192,7 @@ cli.command(
192
192
  "Draft the monthly-report announcement email for maintenance sites (all, or one) for approval."
193
193
  ).action(
194
194
  async (site, opts) => runOrExit(
195
- async () => (await import("../announce-GFLKAPTT.js")).runAnnounceCommand(site, opts),
195
+ async () => (await import("../announce-BRBITWUP.js")).runAnnounceCommand(site, opts),
196
196
  opts
197
197
  )
198
198
  );
@@ -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-VE7CSGWE.js")).runSelftestCommand(kind, site, opts),
204
+ async () => (await import("../selftest-TY7X5ARI.js")).runSelftestCommand(kind, site, opts),
205
205
  opts
206
206
  )
207
207
  );
@@ -216,7 +216,7 @@ cli.command("report [site]", "Draft or send maintenance/testing reports.").optio
216
216
  "Email the operator one daily digest of reports ready for approval (skips when empty)."
217
217
  ).action(
218
218
  async (site, opts) => runOrExit(
219
- async () => (await import("../report-UEYKO6WH.js")).runReportCommand(site, opts),
219
+ async () => (await import("../report-BZ6QNFNM.js")).runReportCommand(site, opts),
220
220
  opts
221
221
  )
222
222
  );
@@ -225,7 +225,7 @@ cli.command(
225
225
  "Sweep the fleet for GitHub signals (Renovate-failing/CI/last-commit) and write Airtable."
226
226
  ).option("--fleet", "Run across every site in the Airtable inventory.").option("--write-airtable", "Write each site's signals back to its Websites row.").action(
227
227
  async (opts) => runOrExit(
228
- async () => (await import("../github-signals-N5JGWHW2.js")).runGitHubSignalsCommand({
228
+ async () => (await import("../github-signals-R4FNU34K.js")).runGitHubSignalsCommand({
229
229
  fleet: opts.fleet,
230
230
  writeAirtable: opts.writeAirtable
231
231
  }),
@@ -243,7 +243,7 @@ cli.command(
243
243
  "Trigger Renovate on fleet sites the security sweep flagged with critical/high vulns."
244
244
  ).option("--fleet", "Run across every active, repo-backed site in the Airtable inventory.").action(
245
245
  async (opts) => runOrExit(
246
- async () => (await import("../renovate-dispatch-H25CQ36P.js")).runRenovateDispatchCommand({
246
+ async () => (await import("../renovate-dispatch-G4T73IUR.js")).runRenovateDispatchCommand({
247
247
  fleet: opts.fleet
248
248
  }),
249
249
  opts
@@ -12,7 +12,7 @@ import {
12
12
  import {
13
13
  ALL_AUDIT_NAMES,
14
14
  runOneAudit
15
- } from "../../chunk-TC7Z5LG7.js";
15
+ } from "../../chunk-WCN54744.js";
16
16
  import "../../chunk-LKGVSM2O.js";
17
17
  import {
18
18
  recordFleetEventsBestEffort
@@ -20,7 +20,7 @@ import {
20
20
  import "../../chunk-PTPTVVY7.js";
21
21
  import "../../chunk-XKKTK6WA.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
26
  import "../../chunk-XXTZBPUY.js";
@@ -1,3 +1,6 @@
1
+ import {
2
+ runRecipeOverSites
3
+ } from "./chunk-VPJ7N6P7.js";
1
4
  import {
2
5
  appendSkipNotice,
3
6
  fleetWorkdir,
@@ -39,8 +42,7 @@ async function runConvertToPnpmCommand(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 convertToPnpm(s));
45
+ const results = await runRecipeOverSites("convert-to-pnpm", sites, (s) => convertToPnpm(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 runConvertToPnpmCommand(site, opts) {
48
50
  export {
49
51
  runConvertToPnpmCommand
50
52
  };
51
- //# sourceMappingURL=convert-to-pnpm-ZO673UFB.js.map
53
+ //# sourceMappingURL=convert-to-pnpm-S4TNJD53.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/convert-to-pnpm.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { convertToPnpm } from \"../../recipes/convert-to-pnpm.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 ConvertToPnpmCommandOptions = {\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 runConvertToPnpmCommand(\n site: string | undefined,\n opts: ConvertToPnpmCommandOptions,\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(\"convert-to-pnpm\", sites, (s) => convertToPnpm(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,wBACpB,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,cAAc,CAAC,CAAC;AAE1F,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":[]}
@@ -16,7 +16,7 @@ import "./chunk-PTPTVVY7.js";
16
16
  import "./chunk-XKKTK6WA.js";
17
17
  import {
18
18
  makeGitHub
19
- } from "./chunk-4GACMVNE.js";
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-N5JGWHW2.js.map
137
+ //# sourceMappingURL=github-signals-R4FNU34K.js.map
package/dist/index.d.ts CHANGED
@@ -69,10 +69,12 @@ type BrowserRunner = {
69
69
  };
70
70
 
71
71
  /** Result of probing a site's latest PRODUCTION Netlify deploy. Every field is
72
- * nullable: a network/parse failure (or a site with no deploys yet) degrades to
73
- * all-nulls rather than throwing, so the audit always returns a verdict.
72
+ * nullable: a site with no production deploy yet degrades to all-nulls (a real
73
+ * "none" verdict). A read FAILURE is NOT represented here it surfaces as
74
+ * `{ ok: false }` on the enclosing `NetlifyDeployFetch` so it can't be mistaken
75
+ * for a verdict. See `NetlifyDeployFetch`.
74
76
  * - `state` is Netlify's raw deploy state (`ready`/`error`/`building`/…), lower-cased,
75
- * or null when it couldn't be read.
77
+ * or null when the site has no production deploy.
76
78
  * - `deployedAt` is the deploy's publish/create time (ISO), or null.
77
79
  * - `logUrl` links to the deploy (its live URL or the Netlify admin/build-log page).
78
80
  * - `errorMessage` is Netlify's `error_message` for a failed build, or null. */
@@ -82,12 +84,28 @@ type NetlifyDeployCheck = {
82
84
  logUrl: string | null;
83
85
  errorMessage: string | null;
84
86
  };
87
+ /** Outcome of probing Netlify, distinguishing "couldn't read" from "read OK".
88
+ * This distinction is load-bearing: `Deploy status` drives the cockpit's Broken
89
+ * band (an ALARM), so a transient read failure must NOT be allowed to clear a
90
+ * real `error` — unlike a degraded "no deploy yet", which is a real verdict.
91
+ * - `{ ok: false }` — the API was unreachable/unreadable (network error, non-2xx,
92
+ * malformed body). The caller persists nothing, leaving the prior status intact.
93
+ * - `{ ok: true, deploy }` — the API answered. `deploy` is the latest production
94
+ * deploy, or all-nulls when the site genuinely has no production deploy yet
95
+ * (a real verdict, safe to persist). */
96
+ type NetlifyDeployFetch = {
97
+ ok: false;
98
+ } | {
99
+ ok: true;
100
+ deploy: NetlifyDeployCheck;
101
+ };
85
102
  /** Injected IO so the check is unit-testable without hitting the Netlify API.
86
- * `fetchLatestProductionDeploy` returns the parsed first (latest) production
87
- * deploy object, or null when the site has none / the call failed. `now` is the
88
- * clock for the checked-at stamp. */
103
+ * `fetchLatestProductionDeploy` returns a `NetlifyDeployFetch` `{ ok: false }`
104
+ * when the call couldn't be read, else `{ ok: true, deploy }` with the latest
105
+ * production deploy (or all-nulls for a site with none). `now` is the clock for
106
+ * the checked-at stamp. */
89
107
  type NetlifyDeployDeps = {
90
- fetchLatestProductionDeploy: (siteId: string) => Promise<NetlifyDeployCheck | null>;
108
+ fetchLatestProductionDeploy: (siteId: string) => Promise<NetlifyDeployFetch>;
91
109
  now: Date;
92
110
  };
93
111
 
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  DEFAULT_INIT_STEPS,
10
10
  a11yFixturesPage,
11
11
  init
12
- } from "./chunk-FX3QBSUF.js";
12
+ } from "./chunk-UCXZYS2W.js";
13
13
  import {
14
14
  convertToPnpm
15
15
  } from "./chunk-2X322ZES.js";
@@ -24,11 +24,11 @@ import {
24
24
  } from "./chunk-ZYBOT5PM.js";
25
25
  import {
26
26
  draftReportForSite
27
- } from "./chunk-M5LX2VSR.js";
27
+ } from "./chunk-SWSFB6IV.js";
28
28
  import "./chunk-6LIWDIXU.js";
29
29
  import {
30
30
  sendApprovedReports
31
- } from "./chunk-QSL3EJGI.js";
31
+ } from "./chunk-XUKSP67U.js";
32
32
  import "./chunk-OGGRFBL4.js";
33
33
  import "./chunk-GECESMVS.js";
34
34
  import {
@@ -36,7 +36,7 @@ import {
36
36
  CHECK_CID,
37
37
  loadBundledImages,
38
38
  renderReportHtml
39
- } from "./chunk-U3MF6RCS.js";
39
+ } from "./chunk-PBDZGBGL.js";
40
40
  import {
41
41
  checklistFor,
42
42
  escapeHtml,
@@ -62,13 +62,13 @@ import {
62
62
  runAudits,
63
63
  runAuditsAcross,
64
64
  securityAudit
65
- } from "./chunk-TC7Z5LG7.js";
65
+ } from "./chunk-WCN54744.js";
66
66
  import "./chunk-LKGVSM2O.js";
67
67
  import "./chunk-G2YRXV26.js";
68
68
  import "./chunk-PTPTVVY7.js";
69
69
  import "./chunk-XKKTK6WA.js";
70
70
  import "./chunk-GASBX52O.js";
71
- import "./chunk-4GACMVNE.js";
71
+ import "./chunk-YEGHUODU.js";
72
72
  import {
73
73
  fromJsonFile,
74
74
  localPath
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-FH7WQHD7.js";
9
9
  import {
10
10
  init
11
- } from "./chunk-FX3QBSUF.js";
11
+ } from "./chunk-UCXZYS2W.js";
12
12
  import "./chunk-2X322ZES.js";
13
13
  import "./chunk-FUD4I2ZW.js";
14
14
  import "./chunk-OQPMZ6BM.js";
@@ -17,13 +17,15 @@ 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-GLT5C6S5.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":[]}
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-CSTLFSGM.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
@@ -19,7 +19,7 @@ import {
19
19
  renderReportHtml,
20
20
  resolveCopy,
21
21
  uploadAttachment
22
- } from "./chunk-U3MF6RCS.js";
22
+ } from "./chunk-PBDZGBGL.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 {
@@ -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-CQM5D6QJ.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ runRecipeOverSites
3
+ } from "./chunk-VPJ7N6P7.js";
1
4
  import {
2
5
  appendSkipNotice,
3
6
  fleetWorkdir,
@@ -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-ILC3DWY4.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,10 +4,10 @@ import {
4
4
  parseAddresses,
5
5
  sendApprovedReports,
6
6
  withGlobalCc
7
- } from "./chunk-QSL3EJGI.js";
7
+ } from "./chunk-XUKSP67U.js";
8
8
  import "./chunk-OGGRFBL4.js";
9
9
  import "./chunk-GECESMVS.js";
10
- import "./chunk-U3MF6RCS.js";
10
+ import "./chunk-PBDZGBGL.js";
11
11
  import "./chunk-OCS7SZUZ.js";
12
12
  import "./chunk-G2YRXV26.js";
13
13
  import "./chunk-PTPTVVY7.js";
@@ -24,4 +24,4 @@ export {
24
24
  sendApprovedReports,
25
25
  withGlobalCc
26
26
  };
27
- //# sourceMappingURL=orchestrate-OX3Z4DUI.js.map
27
+ //# sourceMappingURL=orchestrate-45URUFEK.js.map
@@ -3,7 +3,7 @@ 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,
@@ -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-G4T73IUR.js.map
@@ -5,11 +5,11 @@ import {
5
5
  import {
6
6
  draftReportForSite,
7
7
  readGaConfig
8
- } from "./chunk-M5LX2VSR.js";
8
+ } from "./chunk-SWSFB6IV.js";
9
9
  import {
10
10
  reportTier
11
11
  } from "./chunk-6LIWDIXU.js";
12
- import "./chunk-U3MF6RCS.js";
12
+ import "./chunk-PBDZGBGL.js";
13
13
  import {
14
14
  escapeHtml,
15
15
  listAllReports
@@ -72,7 +72,7 @@ async function runReportCommand(slug, opts) {
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-45URUFEK.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-BZ6QNFNM.js.map