@reddoorla/maintenance 0.54.4 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +3 -1
  2. package/dist/airtable-2BJX4ATJ.js +9 -0
  3. package/dist/airtable-2BJX4ATJ.js.map +1 -0
  4. package/dist/announce-JEVCDDKL.js +171 -0
  5. package/dist/announce-JEVCDDKL.js.map +1 -0
  6. package/dist/bump-deps-O3SOLQYY.js +57 -0
  7. package/dist/bump-deps-O3SOLQYY.js.map +1 -0
  8. package/dist/chunk-2X322ZES.js +99 -0
  9. package/dist/chunk-2X322ZES.js.map +1 -0
  10. package/dist/chunk-4NAOR44V.js +153 -0
  11. package/dist/chunk-4NAOR44V.js.map +1 -0
  12. package/dist/chunk-4PY4I5OR.js +1167 -0
  13. package/dist/chunk-4PY4I5OR.js.map +1 -0
  14. package/dist/chunk-5WL3ET24.js +203 -0
  15. package/dist/chunk-5WL3ET24.js.map +1 -0
  16. package/dist/chunk-6LIWDIXU.js +38 -0
  17. package/dist/chunk-6LIWDIXU.js.map +1 -0
  18. package/dist/chunk-6VAL7XJT.js +52 -0
  19. package/dist/chunk-6VAL7XJT.js.map +1 -0
  20. package/dist/chunk-BWLUNY7L.js +585 -0
  21. package/dist/chunk-BWLUNY7L.js.map +1 -0
  22. package/dist/chunk-CASCWQQX.js +161 -0
  23. package/dist/chunk-CASCWQQX.js.map +1 -0
  24. package/dist/chunk-CLVTVDOU.js +274 -0
  25. package/dist/chunk-CLVTVDOU.js.map +1 -0
  26. package/dist/chunk-D3DQFC32.js +79 -0
  27. package/dist/chunk-D3DQFC32.js.map +1 -0
  28. package/dist/chunk-DIVB6ZF7.js +217 -0
  29. package/dist/chunk-DIVB6ZF7.js.map +1 -0
  30. package/dist/chunk-EYODPUHV.js +37 -0
  31. package/dist/chunk-EYODPUHV.js.map +1 -0
  32. package/dist/chunk-FDIFTIXC.js +70 -0
  33. package/dist/chunk-FDIFTIXC.js.map +1 -0
  34. package/dist/chunk-FUD4I2ZW.js +35 -0
  35. package/dist/chunk-FUD4I2ZW.js.map +1 -0
  36. package/dist/chunk-HG5DTFNF.js +62 -0
  37. package/dist/chunk-HG5DTFNF.js.map +1 -0
  38. package/dist/chunk-HN6I2XWI.js +65 -0
  39. package/dist/chunk-HN6I2XWI.js.map +1 -0
  40. package/dist/chunk-HVOOCK6L.js +84 -0
  41. package/dist/chunk-HVOOCK6L.js.map +1 -0
  42. package/dist/chunk-IMIR7SC2.js +51 -0
  43. package/dist/chunk-IMIR7SC2.js.map +1 -0
  44. package/dist/chunk-J3OPWFZE.js +64 -0
  45. package/dist/chunk-J3OPWFZE.js.map +1 -0
  46. package/dist/chunk-JNXCDUYB.js +211 -0
  47. package/dist/chunk-JNXCDUYB.js.map +1 -0
  48. package/dist/chunk-JQG222CI.js +49 -0
  49. package/dist/chunk-JQG222CI.js.map +1 -0
  50. package/dist/chunk-LKGVSM2O.js +43 -0
  51. package/dist/chunk-LKGVSM2O.js.map +1 -0
  52. package/dist/chunk-LYCKN7ZR.js +41 -0
  53. package/dist/chunk-LYCKN7ZR.js.map +1 -0
  54. package/dist/chunk-O65I7G7G.js +246 -0
  55. package/dist/chunk-O65I7G7G.js.map +1 -0
  56. package/dist/chunk-OCS7SZUZ.js +243 -0
  57. package/dist/chunk-OCS7SZUZ.js.map +1 -0
  58. package/dist/chunk-OGGRFBL4.js +14 -0
  59. package/dist/chunk-OGGRFBL4.js.map +1 -0
  60. package/dist/chunk-OQPMZ6BM.js +368 -0
  61. package/dist/chunk-OQPMZ6BM.js.map +1 -0
  62. package/dist/chunk-OTGB6YQO.js +52 -0
  63. package/dist/chunk-OTGB6YQO.js.map +1 -0
  64. package/dist/chunk-PF6BNYGE.js +162 -0
  65. package/dist/chunk-PF6BNYGE.js.map +1 -0
  66. package/dist/chunk-QTHKOIFJ.js +13 -0
  67. package/dist/chunk-QTHKOIFJ.js.map +1 -0
  68. package/dist/chunk-U5SZ4FOP.js +26 -0
  69. package/dist/chunk-U5SZ4FOP.js.map +1 -0
  70. package/dist/chunk-VXSX2FHO.js +269 -0
  71. package/dist/chunk-VXSX2FHO.js.map +1 -0
  72. package/dist/chunk-W3G7XFBZ.js +444 -0
  73. package/dist/chunk-W3G7XFBZ.js.map +1 -0
  74. package/dist/chunk-WEKL2HYJ.js +31 -0
  75. package/dist/chunk-WEKL2HYJ.js.map +1 -0
  76. package/dist/chunk-WVRPOXKH.js +74 -0
  77. package/dist/chunk-WVRPOXKH.js.map +1 -0
  78. package/dist/chunk-XKOZUVK2.js +121 -0
  79. package/dist/chunk-XKOZUVK2.js.map +1 -0
  80. package/dist/chunk-XO2RUYVM.js +138 -0
  81. package/dist/chunk-XO2RUYVM.js.map +1 -0
  82. package/dist/chunk-XTK5VIQB.js +97 -0
  83. package/dist/chunk-XTK5VIQB.js.map +1 -0
  84. package/dist/chunk-XXTZBPUY.js +9 -0
  85. package/dist/chunk-XXTZBPUY.js.map +1 -0
  86. package/dist/chunk-ZYBOT5PM.js +153 -0
  87. package/dist/chunk-ZYBOT5PM.js.map +1 -0
  88. package/dist/cli/bin.js +75 -7689
  89. package/dist/cli/bin.js.map +1 -1
  90. package/dist/cli/commands/audit.js +37 -2330
  91. package/dist/cli/commands/audit.js.map +1 -1
  92. package/dist/client-EPVO3FEH.js +10 -0
  93. package/dist/client-EPVO3FEH.js.map +1 -0
  94. package/dist/client-JA6QLEDW.js +48 -0
  95. package/dist/client-JA6QLEDW.js.map +1 -0
  96. package/dist/configs/lighthouse.js +4 -31
  97. package/dist/configs/lighthouse.js.map +1 -1
  98. package/dist/configs/playwright-a11y.js +6 -33
  99. package/dist/configs/playwright-a11y.js.map +1 -1
  100. package/dist/convert-to-pnpm-UR64X3OX.js +51 -0
  101. package/dist/convert-to-pnpm-UR64X3OX.js.map +1 -0
  102. package/dist/db-AXKMRTVA.js +23 -0
  103. package/dist/db-AXKMRTVA.js.map +1 -0
  104. package/dist/digest-YTO73BEO.js +408 -0
  105. package/dist/digest-YTO73BEO.js.map +1 -0
  106. package/dist/forms/index.js +3 -8
  107. package/dist/forms/index.js.map +1 -1
  108. package/dist/github-signals-YD64R2AF.js +122 -0
  109. package/dist/github-signals-YD64R2AF.js.map +1 -0
  110. package/dist/index.d.ts +6 -1
  111. package/dist/index.js +102 -4741
  112. package/dist/index.js.map +1 -1
  113. package/dist/init-JITQXFVL.js +85 -0
  114. package/dist/init-JITQXFVL.js.map +1 -0
  115. package/dist/launch-HXHEL6ID.js +207 -0
  116. package/dist/launch-HXHEL6ID.js.map +1 -0
  117. package/dist/lighthouse-airtable-4FKYKFH6.js +12 -0
  118. package/dist/lighthouse-airtable-4FKYKFH6.js.map +1 -0
  119. package/dist/migrate-P2LS4WXI.js +7 -0
  120. package/dist/migrate-P2LS4WXI.js.map +1 -0
  121. package/dist/onboard-TCQOP2W4.js +69 -0
  122. package/dist/onboard-TCQOP2W4.js.map +1 -0
  123. package/dist/orchestrate-RMSBHLQK.js +19 -0
  124. package/dist/orchestrate-RMSBHLQK.js.map +1 -0
  125. package/dist/recipes/sync-configs.js +9 -505
  126. package/dist/recipes/sync-configs.js.map +1 -1
  127. package/dist/renovate-dispatch-ZGLXNPEK.js +97 -0
  128. package/dist/renovate-dispatch-ZGLXNPEK.js.map +1 -0
  129. package/dist/report-SD3CNBOQ.js +240 -0
  130. package/dist/report-SD3CNBOQ.js.map +1 -0
  131. package/dist/resend-G2BJMAQV.js +7 -0
  132. package/dist/resend-G2BJMAQV.js.map +1 -0
  133. package/dist/self-updating-CIUMOMYI.js +61 -0
  134. package/dist/self-updating-CIUMOMYI.js.map +1 -0
  135. package/dist/svelte-codemods-BYRJAU7I.js +51 -0
  136. package/dist/svelte-codemods-BYRJAU7I.js.map +1 -0
  137. package/dist/sync-configs-JPRLAW5J.js +109 -0
  138. package/dist/sync-configs-JPRLAW5J.js.map +1 -0
  139. package/dist/upgrade-ERA45EVR.js +64 -0
  140. package/dist/upgrade-ERA45EVR.js.map +1 -0
  141. package/dist/util/git.js +19 -76
  142. package/dist/util/git.js.map +1 -1
  143. package/dist/util/pkg.js +5 -45
  144. package/dist/util/pkg.js.map +1 -1
  145. package/dist/websites-X5DLC2PC.js +43 -0
  146. package/dist/websites-X5DLC2PC.js.map +1 -0
  147. package/dist/write-audits-to-airtable-CE4POBAF.js +13 -0
  148. package/dist/write-audits-to-airtable-CE4POBAF.js.map +1 -0
  149. package/package.json +13 -16
@@ -0,0 +1,49 @@
1
+ import {
2
+ isHttpUrl
3
+ } from "./chunk-U5SZ4FOP.js";
4
+ import {
5
+ ACTIVE_STATUSES,
6
+ listWebsites,
7
+ siteSlug
8
+ } from "./chunk-CLVTVDOU.js";
9
+
10
+ // src/inventory/airtable.ts
11
+ function fromAirtableBase(base, opts = {}) {
12
+ return async () => {
13
+ const workdir = opts.workdir ?? process.env.REDDOOR_FLEET_WORKDIR;
14
+ if (!workdir) {
15
+ throw new Error(
16
+ "fromAirtableBase requires `workdir` option or REDDOOR_FLEET_WORKDIR env (sites need a local path)"
17
+ );
18
+ }
19
+ const websites = await listWebsites(base);
20
+ return websites.filter((w) => w.status !== null && ACTIVE_STATUSES.has(w.status) && w.url.length > 0).flatMap((w) => {
21
+ const slug = siteSlug(w.name);
22
+ if (slug.length === 0) {
23
+ console.warn(
24
+ `[inventory] skipping "${w.name}" (row ${w.id}): Name has no slug-able characters (empty slug)`
25
+ );
26
+ return [];
27
+ }
28
+ const site = {
29
+ path: `${workdir}/${slug}`,
30
+ name: slug,
31
+ meta: { airtableRowId: w.id, displayName: w.name }
32
+ };
33
+ if (isHttpUrl(w.url)) {
34
+ site.deployedUrl = w.url;
35
+ } else {
36
+ console.warn(
37
+ `[inventory] skipping deployed audit for "${w.name}": url is not http(s): ${JSON.stringify(w.url)}`
38
+ );
39
+ }
40
+ if (w.gitRepo) site.gitRepo = w.gitRepo;
41
+ return [site];
42
+ });
43
+ };
44
+ }
45
+
46
+ export {
47
+ fromAirtableBase
48
+ };
49
+ //# sourceMappingURL=chunk-JQG222CI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/inventory/airtable.ts"],"sourcesContent":["import type { Site, InventoryProvider } from \"../types.js\";\nimport type { AirtableBase } from \"../reports/airtable/client.js\";\nimport { listWebsites, siteSlug, ACTIVE_STATUSES } from \"../reports/airtable/websites.js\";\nimport { isHttpUrl } from \"../util/url.js\";\n\nexport type AirtableInventoryOptions = {\n /**\n * Local workdir to compute each site's path as `{workdir}/{slug}`.\n * Defaults to REDDOOR_FLEET_WORKDIR env var if not provided.\n * Airtable doesn't store local checkout paths, so this is required.\n */\n workdir?: string;\n};\n\n/**\n * Read sites from the Airtable Websites table as an InventoryProvider.\n * Each row becomes one Site; `path` is computed as `{workdir}/{slug}`.\n * Only `maintenance` / `launch period` sites that have a `url` are included\n * (the live sites we audit + report on). The production URL is exposed as\n * `Site.deployedUrl` so the lighthouse audit can run against it with no\n * checkout. `repoUrl` is intentionally NOT set from `url` — a clone source\n * must come from `gitRepo` (`owner/repo`), never the production URL.\n */\nexport function fromAirtableBase(\n base: AirtableBase,\n opts: AirtableInventoryOptions = {},\n): InventoryProvider {\n return async (): Promise<Site[]> => {\n const workdir = opts.workdir ?? process.env.REDDOOR_FLEET_WORKDIR;\n if (!workdir) {\n throw new Error(\n \"fromAirtableBase requires `workdir` option or REDDOOR_FLEET_WORKDIR env (sites need a local path)\",\n );\n }\n const websites = await listWebsites(base);\n return websites\n .filter((w) => w.status !== null && ACTIVE_STATUSES.has(w.status) && w.url.length > 0)\n .flatMap((w) => {\n const slug = siteSlug(w.name);\n // An empty slug (a Name with no slug-able characters) can't form a stable\n // path and — fatally — can't be matched back to its Websites row on\n // write-back: every empty-slug site would collapse under the \"\" key and\n // mis-write or fail. Skip it loudly rather than silently mis-map it.\n if (slug.length === 0) {\n console.warn(\n `[inventory] skipping \"${w.name}\" (row ${w.id}): Name has no slug-able characters (empty slug)`,\n );\n return [];\n }\n const site: Site = {\n path: `${workdir}/${slug}`,\n name: slug,\n meta: { airtableRowId: w.id, displayName: w.name },\n };\n // Scheme-allowlist the Airtable `url` before exposing it as the\n // deployed-audit target (it's handed straight to Chrome/lhci). A\n // `file://`/`gopher://`/internal-host value would be a local-file read\n // or SSRF — skip the deployed audit for that site rather than trust it.\n if (isHttpUrl(w.url)) {\n site.deployedUrl = w.url;\n } else {\n console.warn(\n `[inventory] skipping deployed audit for \"${w.name}\": url is not http(s): ${JSON.stringify(w.url)}`,\n );\n }\n if (w.gitRepo) site.gitRepo = w.gitRepo;\n return [site];\n });\n };\n}\n"],"mappings":";;;;;;;;;;AAuBO,SAAS,iBACd,MACA,OAAiC,CAAC,GACf;AACnB,SAAO,YAA6B;AAClC,UAAM,UAAU,KAAK,WAAW,QAAQ,IAAI;AAC5C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,WAAW,MAAM,aAAa,IAAI;AACxC,WAAO,SACJ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,gBAAgB,IAAI,EAAE,MAAM,KAAK,EAAE,IAAI,SAAS,CAAC,EACpF,QAAQ,CAAC,MAAM;AACd,YAAM,OAAO,SAAS,EAAE,IAAI;AAK5B,UAAI,KAAK,WAAW,GAAG;AACrB,gBAAQ;AAAA,UACN,yBAAyB,EAAE,IAAI,UAAU,EAAE,EAAE;AAAA,QAC/C;AACA,eAAO,CAAC;AAAA,MACV;AACA,YAAM,OAAa;AAAA,QACjB,MAAM,GAAG,OAAO,IAAI,IAAI;AAAA,QACxB,MAAM;AAAA,QACN,MAAM,EAAE,eAAe,EAAE,IAAI,aAAa,EAAE,KAAK;AAAA,MACnD;AAKA,UAAI,UAAU,EAAE,GAAG,GAAG;AACpB,aAAK,cAAc,EAAE;AAAA,MACvB,OAAO;AACL,gBAAQ;AAAA,UACN,4CAA4C,EAAE,IAAI,0BAA0B,KAAK,UAAU,EAAE,GAAG,CAAC;AAAA,QACnG;AAAA,MACF;AACA,UAAI,EAAE,QAAS,MAAK,UAAU,EAAE;AAChC,aAAO,CAAC,IAAI;AAAA,IACd,CAAC;AAAA,EACL;AACF;","names":[]}
@@ -0,0 +1,43 @@
1
+ // src/configs/baseline-versions.ts
2
+ var baselineVersions = {
3
+ // SvelteKit core
4
+ svelte: "^5.55.10",
5
+ "@sveltejs/kit": "^2.61.1",
6
+ "@sveltejs/adapter-netlify": "^6.0.4",
7
+ "@sveltejs/adapter-auto": "^7.0.1",
8
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
9
+ "svelte-check": "^4.4.8",
10
+ // Build tooling
11
+ vite: "^8.0.14",
12
+ vitest: "^4.1.7",
13
+ typescript: "^6.0.3",
14
+ // Tailwind 4
15
+ tailwindcss: "^4.3.0",
16
+ "@tailwindcss/vite": "^4.3.0",
17
+ // Prismic
18
+ "@prismicio/client": "^7.21.8",
19
+ "@prismicio/svelte": "^2.2.1",
20
+ "@slicemachine/adapter-sveltekit": "^0.3.96",
21
+ "slice-machine-ui": "^2.21.3",
22
+ // Test tooling
23
+ "@playwright/test": "^1.60.0",
24
+ "@axe-core/playwright": "^4.11.3",
25
+ "@lhci/cli": "^0.15.1",
26
+ // Lint
27
+ eslint: "^10.4.0",
28
+ "eslint-plugin-svelte": "^3.18.0",
29
+ "eslint-config-prettier": "^10.1.8",
30
+ prettier: "^3.8.3",
31
+ "prettier-plugin-svelte": "^4.0.1",
32
+ "typescript-eslint": "^8.60.0",
33
+ "@eslint/js": "^10.0.1",
34
+ globals: "^17.6.0",
35
+ // Misc
36
+ "@lucide/svelte": "^1.17.0",
37
+ "@zerodevx/svelte-img": "^2.1.2"
38
+ };
39
+
40
+ export {
41
+ baselineVersions
42
+ };
43
+ //# sourceMappingURL=chunk-LKGVSM2O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/configs/baseline-versions.ts"],"sourcesContent":["// Curated map of the framework deps reddoor sites should stay close to.\n// Refreshed at each package release from reddoor-starter's package.json.\n// Versions are caret ranges to mirror what `pnpm add` would produce.\n\nexport const baselineVersions: Record<string, string> = {\n // SvelteKit core\n svelte: \"^5.55.10\",\n \"@sveltejs/kit\": \"^2.61.1\",\n \"@sveltejs/adapter-netlify\": \"^6.0.4\",\n \"@sveltejs/adapter-auto\": \"^7.0.1\",\n \"@sveltejs/vite-plugin-svelte\": \"^7.1.2\",\n \"svelte-check\": \"^4.4.8\",\n\n // Build tooling\n vite: \"^8.0.14\",\n vitest: \"^4.1.7\",\n typescript: \"^6.0.3\",\n\n // Tailwind 4\n tailwindcss: \"^4.3.0\",\n \"@tailwindcss/vite\": \"^4.3.0\",\n\n // Prismic\n \"@prismicio/client\": \"^7.21.8\",\n \"@prismicio/svelte\": \"^2.2.1\",\n \"@slicemachine/adapter-sveltekit\": \"^0.3.96\",\n \"slice-machine-ui\": \"^2.21.3\",\n\n // Test tooling\n \"@playwright/test\": \"^1.60.0\",\n \"@axe-core/playwright\": \"^4.11.3\",\n \"@lhci/cli\": \"^0.15.1\",\n\n // Lint\n eslint: \"^10.4.0\",\n \"eslint-plugin-svelte\": \"^3.18.0\",\n \"eslint-config-prettier\": \"^10.1.8\",\n prettier: \"^3.8.3\",\n \"prettier-plugin-svelte\": \"^4.0.1\",\n \"typescript-eslint\": \"^8.60.0\",\n \"@eslint/js\": \"^10.0.1\",\n globals: \"^17.6.0\",\n\n // Misc\n \"@lucide/svelte\": \"^1.17.0\",\n \"@zerodevx/svelte-img\": \"^2.1.2\",\n};\n\nexport default baselineVersions;\n"],"mappings":";AAIO,IAAM,mBAA2C;AAAA;AAAA,EAEtD,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,gCAAgC;AAAA,EAChC,gBAAgB;AAAA;AAAA,EAGhB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,YAAY;AAAA;AAAA,EAGZ,aAAa;AAAA,EACb,qBAAqB;AAAA;AAAA,EAGrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,mCAAmC;AAAA,EACnC,oBAAoB;AAAA;AAAA,EAGpB,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,aAAa;AAAA;AAAA,EAGb,QAAQ;AAAA,EACR,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,UAAU;AAAA,EACV,0BAA0B;AAAA,EAC1B,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,SAAS;AAAA;AAAA,EAGT,kBAAkB;AAAA,EAClB,wBAAwB;AAC1B;","names":[]}
@@ -0,0 +1,41 @@
1
+ // src/configs/playwright-a11y.ts
2
+ import { defineConfig, devices } from "@playwright/test";
3
+ var a11yRoutes = [
4
+ { path: "/dev/a11y-fixtures", name: "a11y fixtures" },
5
+ { path: "/dev/animate-in", name: "animate-in demo" }
6
+ ];
7
+ var smokeRoutes = [{ path: "/", name: "home" }];
8
+ var playwrightA11yConfig = defineConfig({
9
+ testDir: "tests",
10
+ testMatch: /.*\.spec\.ts$/,
11
+ fullyParallel: true,
12
+ forbidOnly: !!process.env.CI,
13
+ retries: process.env.CI ? 2 : 0,
14
+ reporter: process.env.CI ? "github" : "list",
15
+ use: {
16
+ baseURL: "http://localhost:5173",
17
+ trace: "on-first-retry"
18
+ },
19
+ projects: [
20
+ {
21
+ name: "chromium",
22
+ use: { ...devices["Desktop Chrome"] }
23
+ }
24
+ ],
25
+ webServer: {
26
+ // Portable across pnpm and npm sites — pnpm respects `npm run` too.
27
+ command: "npm run vite:dev",
28
+ url: "http://localhost:5173/dev/a11y-fixtures",
29
+ reuseExistingServer: !process.env.CI,
30
+ timeout: 12e4
31
+ }
32
+ });
33
+ var playwright_a11y_default = playwrightA11yConfig;
34
+
35
+ export {
36
+ a11yRoutes,
37
+ smokeRoutes,
38
+ playwrightA11yConfig,
39
+ playwright_a11y_default
40
+ };
41
+ //# sourceMappingURL=chunk-LYCKN7ZR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/configs/playwright-a11y.ts"],"sourcesContent":["import { defineConfig, devices, type PlaywrightTestConfig } from \"@playwright/test\";\n\nexport type A11yRoute = { path: string; name: string };\n\nexport const a11yRoutes: A11yRoute[] = [\n { path: \"/dev/a11y-fixtures\", name: \"a11y fixtures\" },\n { path: \"/dev/animate-in\", name: \"animate-in demo\" },\n];\n\n// Routes smoke-loaded for client-side (hydration) errors only — NOT axe-scanned.\n// Catches the class of bug where build + SSR succeed but client hydration throws\n// and blanks the page (data-dynamiq 2026-06-09: a Svelte 4->5 `run()` referenced\n// a `$state` declared after it → TDZ ReferenceError on hydrate). `/` is the one\n// route every site has; real routes carry a11y debt we don't gate on here, so we\n// assert only that they don't crash on hydrate.\nexport const smokeRoutes: A11yRoute[] = [{ path: \"/\", name: \"home\" }];\n\nexport const playwrightA11yConfig: PlaywrightTestConfig = defineConfig({\n testDir: \"tests\",\n testMatch: /.*\\.spec\\.ts$/,\n fullyParallel: true,\n forbidOnly: !!process.env.CI,\n retries: process.env.CI ? 2 : 0,\n reporter: process.env.CI ? \"github\" : \"list\",\n use: {\n baseURL: \"http://localhost:5173\",\n trace: \"on-first-retry\",\n },\n projects: [\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n ],\n webServer: {\n // Portable across pnpm and npm sites — pnpm respects `npm run` too.\n command: \"npm run vite:dev\",\n url: \"http://localhost:5173/dev/a11y-fixtures\",\n reuseExistingServer: !process.env.CI,\n timeout: 120_000,\n },\n});\n\nexport default playwrightA11yConfig;\n"],"mappings":";AAAA,SAAS,cAAc,eAA0C;AAI1D,IAAM,aAA0B;AAAA,EACrC,EAAE,MAAM,sBAAsB,MAAM,gBAAgB;AAAA,EACpD,EAAE,MAAM,mBAAmB,MAAM,kBAAkB;AACrD;AAQO,IAAM,cAA2B,CAAC,EAAE,MAAM,KAAK,MAAM,OAAO,CAAC;AAE7D,IAAM,uBAA6C,aAAa;AAAA,EACrE,SAAS;AAAA,EACT,WAAW;AAAA,EACX,eAAe;AAAA,EACf,YAAY,CAAC,CAAC,QAAQ,IAAI;AAAA,EAC1B,SAAS,QAAQ,IAAI,KAAK,IAAI;AAAA,EAC9B,UAAU,QAAQ,IAAI,KAAK,WAAW;AAAA,EACtC,KAAK;AAAA,IACH,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,UAAU;AAAA,IACR;AAAA,MACE,MAAM;AAAA,MACN,KAAK,EAAE,GAAG,QAAQ,gBAAgB,EAAE;AAAA,IACtC;AAAA,EACF;AAAA,EACA,WAAW;AAAA;AAAA,IAET,SAAS;AAAA,IACT,KAAK;AAAA,IACL,qBAAqB,CAAC,QAAQ,IAAI;AAAA,IAClC,SAAS;AAAA,EACX;AACF,CAAC;AAED,IAAO,0BAAQ;","names":[]}
@@ -0,0 +1,246 @@
1
+ import {
2
+ applyGotchaCodemods
3
+ } from "./chunk-OQPMZ6BM.js";
4
+ import {
5
+ withRecipe
6
+ } from "./chunk-XKOZUVK2.js";
7
+ import {
8
+ bumpDep,
9
+ readPackageJson,
10
+ writePackageJson
11
+ } from "./chunk-OTGB6YQO.js";
12
+ import {
13
+ defaultSpawn
14
+ } from "./chunk-HVOOCK6L.js";
15
+
16
+ // src/recipes/svelte-5/index.ts
17
+ import { join as join5 } from "path";
18
+
19
+ // src/recipes/svelte-5/step-bump-versions.ts
20
+ import { join } from "path";
21
+ var SVELTE_5_VERSIONS = {
22
+ svelte: "^5.55.5",
23
+ "@sveltejs/kit": "^2.59.0",
24
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
25
+ "@sveltejs/adapter-netlify": "^6.0.4",
26
+ "@sveltejs/adapter-auto": "^7.0.0",
27
+ vite: "^8.0.10",
28
+ "svelte-check": "^4.4.7",
29
+ typescript: "^6.0.3",
30
+ "typescript-svelte-plugin": "^0.3.52"
31
+ };
32
+ async function bumpToSvelte5Versions(cwd) {
33
+ const pkgPath = join(cwd, "package.json");
34
+ const pkg = await readPackageJson(pkgPath);
35
+ let next = pkg;
36
+ for (const [name, version] of Object.entries(SVELTE_5_VERSIONS)) {
37
+ next = bumpDep(next, name, version, { mode: "bump-only" });
38
+ }
39
+ if (next === pkg) return false;
40
+ await writePackageJson(pkgPath, next);
41
+ return true;
42
+ }
43
+
44
+ // src/recipes/svelte-5/step-svelte-config.ts
45
+ import { readFile, writeFile } from "fs/promises";
46
+ import { join as join2 } from "path";
47
+ var VITE_PLUGIN_PKG = "@sveltejs/vite-plugin-svelte";
48
+ var IMPORT_FROM_VITE_PLUGIN = new RegExp(
49
+ String.raw`^import\s+\{\s*([^}]+?)\s*\}\s+from\s+["']` + VITE_PLUGIN_PKG.replace(/[/]/g, "\\/") + String.raw`["'];?[ \t]*\n`,
50
+ "m"
51
+ );
52
+ function dropVitePreprocessImport(source) {
53
+ return source.replace(IMPORT_FROM_VITE_PLUGIN, (full, names) => {
54
+ const remaining = names.split(",").map((n) => n.trim()).filter((n) => n.length > 0 && n !== "vitePreprocess");
55
+ if (remaining.length === 0) return "";
56
+ return `import { ${remaining.join(", ")} } from "${VITE_PLUGIN_PKG}";
57
+ `;
58
+ });
59
+ }
60
+ function findMatchingParen(source, openIdx) {
61
+ if (source[openIdx] !== "(") return -1;
62
+ let depth = 0;
63
+ for (let i = openIdx; i < source.length; i++) {
64
+ const ch = source[i];
65
+ if (ch === "(") depth++;
66
+ else if (ch === ")") {
67
+ depth--;
68
+ if (depth === 0) return i;
69
+ }
70
+ }
71
+ return -1;
72
+ }
73
+ function dropPreprocessKey(source) {
74
+ const startRe = /^(\s*)preprocess:\s*vitePreprocess\(/m;
75
+ const m = startRe.exec(source);
76
+ if (!m) return source;
77
+ const indent = m[1] ?? "";
78
+ const parenOpenAbs = m.index + m[0].length - 1;
79
+ const parenCloseAbs = findMatchingParen(source, parenOpenAbs);
80
+ if (parenCloseAbs < 0) return source;
81
+ let tailIdx = parenCloseAbs + 1;
82
+ while (tailIdx < source.length && /[ \t,]/.test(source[tailIdx] ?? "")) tailIdx++;
83
+ if (source[tailIdx] === "\n") tailIdx++;
84
+ return source.slice(0, m.index) + source.slice(tailIdx).replace(new RegExp(`^${indent}\\n`), "");
85
+ }
86
+ async function migrateSvelteConfig(cwd) {
87
+ const path = join2(cwd, "svelte.config.js");
88
+ let src;
89
+ try {
90
+ src = await readFile(path, "utf-8");
91
+ } catch {
92
+ return false;
93
+ }
94
+ let next = src;
95
+ next = dropPreprocessKey(next);
96
+ next = dropVitePreprocessImport(next);
97
+ if (next === src) return false;
98
+ await writeFile(path, next, "utf-8");
99
+ return true;
100
+ }
101
+
102
+ // src/recipes/svelte-5/step-svelte-migrate.ts
103
+ async function runSvelteMigrate(cwd, spawn = defaultSpawn) {
104
+ try {
105
+ const { code, stderr } = await spawn(
106
+ "npx",
107
+ ["--yes", "svelte-migrate", "svelte-5", "--no-install"],
108
+ { cwd, timeoutMs: 5 * 6e4 }
109
+ );
110
+ if (code !== 0) {
111
+ return { ran: false, stderr };
112
+ }
113
+ return { ran: true, stderr };
114
+ } catch (err) {
115
+ const e = err;
116
+ if (e.code === "ENOENT" || /ENOENT/.test(String(err))) {
117
+ return { ran: false, stderr: "npx unavailable" };
118
+ }
119
+ throw err;
120
+ }
121
+ }
122
+
123
+ // src/recipes/svelte-5/step-tailwind-upgrade.ts
124
+ import { join as join3 } from "path";
125
+ async function upgradeTailwind(cwd, spawn = defaultSpawn) {
126
+ const pkg = await readPackageJson(join3(cwd, "package.json"));
127
+ const tailwindVersion = pkg.devDependencies?.tailwindcss ?? pkg.dependencies?.tailwindcss;
128
+ if (!tailwindVersion) return { ran: false, reason: "tailwindcss not installed" };
129
+ if (/^\^?4\./.test(tailwindVersion)) return { ran: false, reason: "already on tailwind 4.x" };
130
+ try {
131
+ const { code, stderr } = await spawn("npx", ["--yes", "@tailwindcss/upgrade", "--force"], {
132
+ cwd,
133
+ timeoutMs: 5 * 6e4
134
+ });
135
+ if (code !== 0) return { ran: false, reason: stderr.slice(0, 200) };
136
+ return { ran: true };
137
+ } catch (err) {
138
+ const e = err;
139
+ if (e.code === "ENOENT" || /ENOENT/.test(String(err))) {
140
+ return { ran: false, reason: "npx unavailable" };
141
+ }
142
+ throw err;
143
+ }
144
+ }
145
+
146
+ // src/recipes/svelte-5/step-verify.ts
147
+ async function verifyMigration(cwd, spawn = defaultSpawn) {
148
+ let install;
149
+ try {
150
+ install = await spawn("pnpm", ["install"], { cwd, timeoutMs: 10 * 6e4 });
151
+ } catch {
152
+ install = { skipped: true };
153
+ }
154
+ let check;
155
+ try {
156
+ check = await spawn("pnpm", ["run", "check"], { cwd, timeoutMs: 5 * 6e4 });
157
+ } catch {
158
+ check = { skipped: true };
159
+ }
160
+ return { install, check };
161
+ }
162
+
163
+ // src/recipes/svelte-5/step-summary.ts
164
+ import { writeFile as writeFile2 } from "fs/promises";
165
+ import { join as join4 } from "path";
166
+ async function writeMigrationSummary(input) {
167
+ const lines = [
168
+ `# Svelte 4 \u2192 5 migration summary`,
169
+ ``,
170
+ `Generated by @reddoorla/maintenance.`,
171
+ ``,
172
+ `- svelte-migrate run: ${input.svelteMigrateRan ? "yes" : "no"}`,
173
+ `- @tailwindcss/upgrade run: ${input.tailwindUpgraded ? "yes" : "no"}`,
174
+ `- .svelte files touched by gotcha codemods: ${input.filesChangedByCodemods}`,
175
+ ``,
176
+ `Next steps:`,
177
+ `- Run \`pnpm run check\` and resolve any remaining warnings.`,
178
+ `- Spot-check rune migrations in components that use \`reactive\` statements.`,
179
+ `- Verify Playwright a11y tests still pass.`
180
+ ];
181
+ const content = lines.join("\n") + "\n";
182
+ const path = join4(input.cwd, "MIGRATION_SVELTE_5.md");
183
+ await writeFile2(path, content, "utf-8");
184
+ return path;
185
+ }
186
+
187
+ // src/recipes/svelte-5/index.ts
188
+ async function alreadyOnSvelte5(cwd) {
189
+ try {
190
+ const pkg = await readPackageJson(join5(cwd, "package.json"));
191
+ const v = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte;
192
+ return !!v && /^\^?5\./.test(v);
193
+ } catch {
194
+ return false;
195
+ }
196
+ }
197
+ async function upgradeSvelte4to5(site, opts = {}) {
198
+ const spawn = opts.spawn ?? defaultSpawn;
199
+ return withRecipe({
200
+ name: "svelte-4-to-5",
201
+ site,
202
+ plan: async () => {
203
+ if (await alreadyOnSvelte5(site.path)) {
204
+ return { kind: "noop", notes: "site already declares svelte ^5.x" };
205
+ }
206
+ return { kind: "apply", plan: true };
207
+ },
208
+ apply: async (_plan, { commit, cwd }) => {
209
+ const bumped = await bumpToSvelte5Versions(cwd);
210
+ if (bumped) {
211
+ await commit("chore(svelte5): bump svelte/kit/vite/vite-plugin-svelte");
212
+ }
213
+ const configChanged = await migrateSvelteConfig(cwd);
214
+ if (configChanged) {
215
+ await commit("refactor(svelte5): migrate svelte.config.js (drop vitePreprocess)");
216
+ }
217
+ const migrate = await runSvelteMigrate(cwd, spawn);
218
+ if (migrate.ran) {
219
+ await commit("refactor(svelte5): run official svelte-migrate codemod");
220
+ }
221
+ const tw = await upgradeTailwind(cwd, spawn);
222
+ if (tw.ran) {
223
+ await commit("chore(svelte5): tailwindcss 3 \u2192 4 upgrade");
224
+ }
225
+ const codemods = await applyGotchaCodemods(cwd);
226
+ if (codemods.filesChanged > 0) {
227
+ await commit(`refactor(svelte5): apply gotcha codemods (${codemods.filesChanged} files)`);
228
+ }
229
+ await verifyMigration(cwd, spawn);
230
+ await commit("chore(svelte5): pnpm install + check");
231
+ await writeMigrationSummary({
232
+ cwd,
233
+ filesChangedByCodemods: codemods.filesChanged,
234
+ svelteMigrateRan: migrate.ran,
235
+ tailwindUpgraded: tw.ran
236
+ });
237
+ await commit("docs(svelte5): add MIGRATION_SVELTE_5.md summary");
238
+ return { kind: "ok" };
239
+ }
240
+ });
241
+ }
242
+
243
+ export {
244
+ upgradeSvelte4to5
245
+ };
246
+ //# sourceMappingURL=chunk-O65I7G7G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recipes/svelte-5/index.ts","../src/recipes/svelte-5/step-bump-versions.ts","../src/recipes/svelte-5/step-svelte-config.ts","../src/recipes/svelte-5/step-svelte-migrate.ts","../src/recipes/svelte-5/step-tailwind-upgrade.ts","../src/recipes/svelte-5/step-verify.ts","../src/recipes/svelte-5/step-summary.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport type { RecipeResult, Site } from \"../../types.js\";\nimport { readPackageJson } from \"../../util/pkg.js\";\nimport { defaultSpawn, type SpawnFn } from \"../../audits/util/spawn.js\";\nimport { bumpToSvelte5Versions } from \"./step-bump-versions.js\";\nimport { migrateSvelteConfig } from \"./step-svelte-config.js\";\nimport { runSvelteMigrate } from \"./step-svelte-migrate.js\";\nimport { upgradeTailwind } from \"./step-tailwind-upgrade.js\";\nimport { applyGotchaCodemods } from \"./step-gotchas.js\";\nimport { verifyMigration } from \"./step-verify.js\";\nimport { writeMigrationSummary } from \"./step-summary.js\";\nimport { withRecipe } from \"../_with-recipe.js\";\n\nexport type UpgradeSvelte4to5Options = {\n spawn?: SpawnFn;\n};\n\nasync function alreadyOnSvelte5(cwd: string): Promise<boolean> {\n try {\n const pkg = await readPackageJson(join(cwd, \"package.json\"));\n const v = pkg.devDependencies?.svelte ?? pkg.dependencies?.svelte;\n return !!v && /^\\^?5\\./.test(v);\n } catch {\n return false;\n }\n}\n\nexport async function upgradeSvelte4to5(\n site: Site,\n opts: UpgradeSvelte4to5Options = {},\n): Promise<RecipeResult> {\n const spawn = opts.spawn ?? defaultSpawn;\n\n return withRecipe<true>({\n name: \"svelte-4-to-5\",\n site,\n plan: async () => {\n if (await alreadyOnSvelte5(site.path)) {\n return { kind: \"noop\", notes: \"site already declares svelte ^5.x\" };\n }\n return { kind: \"apply\", plan: true };\n },\n apply: async (_plan, { commit, cwd }) => {\n const bumped = await bumpToSvelte5Versions(cwd);\n if (bumped) {\n await commit(\"chore(svelte5): bump svelte/kit/vite/vite-plugin-svelte\");\n }\n\n const configChanged = await migrateSvelteConfig(cwd);\n if (configChanged) {\n await commit(\"refactor(svelte5): migrate svelte.config.js (drop vitePreprocess)\");\n }\n\n const migrate = await runSvelteMigrate(cwd, spawn);\n if (migrate.ran) {\n await commit(\"refactor(svelte5): run official svelte-migrate codemod\");\n }\n\n const tw = await upgradeTailwind(cwd, spawn);\n if (tw.ran) {\n await commit(\"chore(svelte5): tailwindcss 3 → 4 upgrade\");\n }\n\n const codemods = await applyGotchaCodemods(cwd);\n if (codemods.filesChanged > 0) {\n await commit(`refactor(svelte5): apply gotcha codemods (${codemods.filesChanged} files)`);\n }\n\n await verifyMigration(cwd, spawn);\n await commit(\"chore(svelte5): pnpm install + check\");\n\n await writeMigrationSummary({\n cwd,\n filesChangedByCodemods: codemods.filesChanged,\n svelteMigrateRan: migrate.ran,\n tailwindUpgraded: tw.ran,\n });\n await commit(\"docs(svelte5): add MIGRATION_SVELTE_5.md summary\");\n\n return { kind: \"ok\" };\n },\n });\n}\n","import { join } from \"node:path\";\nimport { readPackageJson, writePackageJson, bumpDep } from \"../../util/pkg.js\";\n\nconst SVELTE_5_VERSIONS: Record<string, string> = {\n svelte: \"^5.55.5\",\n \"@sveltejs/kit\": \"^2.59.0\",\n \"@sveltejs/vite-plugin-svelte\": \"^7.0.0\",\n \"@sveltejs/adapter-netlify\": \"^6.0.4\",\n \"@sveltejs/adapter-auto\": \"^7.0.0\",\n vite: \"^8.0.10\",\n \"svelte-check\": \"^4.4.7\",\n typescript: \"^6.0.3\",\n \"typescript-svelte-plugin\": \"^0.3.52\",\n};\n\nexport async function bumpToSvelte5Versions(cwd: string): Promise<boolean> {\n const pkgPath = join(cwd, \"package.json\");\n const pkg = await readPackageJson(pkgPath);\n let next = pkg;\n // bump-only: a svelte-4 site that doesn't declare e.g. adapter-netlify\n // should not get it added during the upgrade.\n for (const [name, version] of Object.entries(SVELTE_5_VERSIONS)) {\n next = bumpDep(next, name, version, { mode: \"bump-only\" });\n }\n if (next === pkg) return false;\n await writePackageJson(pkgPath, next);\n return true;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nconst VITE_PLUGIN_PKG = \"@sveltejs/vite-plugin-svelte\";\n\n/** Match an import statement that pulls one or more named bindings from\n * `@sveltejs/vite-plugin-svelte`. Group 1 is the comma-separated name list. */\nconst IMPORT_FROM_VITE_PLUGIN = new RegExp(\n String.raw`^import\\s+\\{\\s*([^}]+?)\\s*\\}\\s+from\\s+[\"']` +\n VITE_PLUGIN_PKG.replace(/[/]/g, \"\\\\/\") +\n String.raw`[\"'];?[ \\t]*\\n`,\n \"m\",\n);\n\n/** Rewrite the import to drop only `vitePreprocess`, preserving any other\n * named bindings. If `vitePreprocess` was the sole import, the whole line\n * is removed. */\nfunction dropVitePreprocessImport(source: string): string {\n return source.replace(IMPORT_FROM_VITE_PLUGIN, (full, names: string) => {\n const remaining = names\n .split(\",\")\n .map((n) => n.trim())\n .filter((n) => n.length > 0 && n !== \"vitePreprocess\");\n if (remaining.length === 0) return \"\"; // drop entire line including its trailing newline\n return `import { ${remaining.join(\", \")} } from \"${VITE_PLUGIN_PKG}\";\\n`;\n });\n}\n\n/** Find the end of a balanced-paren call starting at `openIdx`, which must\n * point at the `(` character. Returns the index of the matching `)`, or -1\n * if unbalanced. */\nfunction findMatchingParen(source: string, openIdx: number): number {\n if (source[openIdx] !== \"(\") return -1;\n let depth = 0;\n for (let i = openIdx; i < source.length; i++) {\n const ch = source[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\n/** Remove a `preprocess: vitePreprocess(<anything>),?` key from a config\n * object. Handles the call with empty parens or with an options object. */\nfunction dropPreprocessKey(source: string): string {\n // Anchor on the start of the preprocess key on its own line so we don't\n // also strip whitespace / commas from neighboring keys.\n const startRe = /^(\\s*)preprocess:\\s*vitePreprocess\\(/m;\n const m = startRe.exec(source);\n if (!m) return source;\n\n const indent = m[1] ?? \"\";\n const parenOpenAbs = m.index + m[0].length - 1; // points at `(`\n const parenCloseAbs = findMatchingParen(source, parenOpenAbs);\n if (parenCloseAbs < 0) return source;\n\n // Consume an optional trailing comma and whitespace through end-of-line.\n let tailIdx = parenCloseAbs + 1;\n while (tailIdx < source.length && /[ \\t,]/.test(source[tailIdx] ?? \"\")) tailIdx++;\n if (source[tailIdx] === \"\\n\") tailIdx++;\n\n return source.slice(0, m.index) + source.slice(tailIdx).replace(new RegExp(`^${indent}\\\\n`), \"\");\n}\n\nexport async function migrateSvelteConfig(cwd: string): Promise<boolean> {\n const path = join(cwd, \"svelte.config.js\");\n let src: string;\n try {\n src = await readFile(path, \"utf-8\");\n } catch {\n return false;\n }\n\n let next = src;\n next = dropPreprocessKey(next);\n next = dropVitePreprocessImport(next);\n\n if (next === src) return false;\n await writeFile(path, next, \"utf-8\");\n return true;\n}\n","import { defaultSpawn, type SpawnFn } from \"../../audits/util/spawn.js\";\n\nexport async function runSvelteMigrate(\n cwd: string,\n spawn: SpawnFn = defaultSpawn,\n): Promise<{ ran: boolean; stderr: string }> {\n try {\n const { code, stderr } = await spawn(\n \"npx\",\n [\"--yes\", \"svelte-migrate\", \"svelte-5\", \"--no-install\"],\n { cwd, timeoutMs: 5 * 60_000 },\n );\n if (code !== 0) {\n return { ran: false, stderr };\n }\n return { ran: true, stderr };\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\" || /ENOENT/.test(String(err))) {\n return { ran: false, stderr: \"npx unavailable\" };\n }\n throw err;\n }\n}\n","import { readPackageJson } from \"../../util/pkg.js\";\nimport { join } from \"node:path\";\nimport { defaultSpawn, type SpawnFn } from \"../../audits/util/spawn.js\";\n\nexport async function upgradeTailwind(\n cwd: string,\n spawn: SpawnFn = defaultSpawn,\n): Promise<{ ran: boolean; reason?: string }> {\n const pkg = await readPackageJson(join(cwd, \"package.json\"));\n const tailwindVersion = pkg.devDependencies?.tailwindcss ?? pkg.dependencies?.tailwindcss;\n if (!tailwindVersion) return { ran: false, reason: \"tailwindcss not installed\" };\n if (/^\\^?4\\./.test(tailwindVersion)) return { ran: false, reason: \"already on tailwind 4.x\" };\n\n try {\n const { code, stderr } = await spawn(\"npx\", [\"--yes\", \"@tailwindcss/upgrade\", \"--force\"], {\n cwd,\n timeoutMs: 5 * 60_000,\n });\n if (code !== 0) return { ran: false, reason: stderr.slice(0, 200) };\n return { ran: true };\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === \"ENOENT\" || /ENOENT/.test(String(err))) {\n return { ran: false, reason: \"npx unavailable\" };\n }\n throw err;\n }\n}\n","import { defaultSpawn, type SpawnFn, type SpawnResult } from \"../../audits/util/spawn.js\";\n\nexport type VerifyResult = {\n install: SpawnResult | { skipped: true };\n check: SpawnResult | { skipped: true };\n};\n\nexport async function verifyMigration(\n cwd: string,\n spawn: SpawnFn = defaultSpawn,\n): Promise<VerifyResult> {\n let install: VerifyResult[\"install\"];\n try {\n install = await spawn(\"pnpm\", [\"install\"], { cwd, timeoutMs: 10 * 60_000 });\n } catch {\n install = { skipped: true };\n }\n\n let check: VerifyResult[\"check\"];\n try {\n check = await spawn(\"pnpm\", [\"run\", \"check\"], { cwd, timeoutMs: 5 * 60_000 });\n } catch {\n check = { skipped: true };\n }\n\n return { install, check };\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport type SummaryInput = {\n cwd: string;\n filesChangedByCodemods: number;\n svelteMigrateRan: boolean;\n tailwindUpgraded: boolean;\n};\n\nexport async function writeMigrationSummary(input: SummaryInput): Promise<string> {\n const lines = [\n `# Svelte 4 → 5 migration summary`,\n ``,\n `Generated by @reddoorla/maintenance.`,\n ``,\n `- svelte-migrate run: ${input.svelteMigrateRan ? \"yes\" : \"no\"}`,\n `- @tailwindcss/upgrade run: ${input.tailwindUpgraded ? \"yes\" : \"no\"}`,\n `- .svelte files touched by gotcha codemods: ${input.filesChangedByCodemods}`,\n ``,\n `Next steps:`,\n `- Run \\`pnpm run check\\` and resolve any remaining warnings.`,\n `- Spot-check rune migrations in components that use \\`reactive\\` statements.`,\n `- Verify Playwright a11y tests still pass.`,\n ];\n const content = lines.join(\"\\n\") + \"\\n\";\n const path = join(input.cwd, \"MIGRATION_SVELTE_5.md\");\n await writeFile(path, content, \"utf-8\");\n return path;\n}\n"],"mappings":"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","names":["join","join","join","join","writeFile","join","join"]}