opencode-skills-collection 3.0.35 → 3.0.36

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 (238) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +15 -1
  2. package/bundled-skills/accesslint-audit/SKILL.md +115 -0
  3. package/bundled-skills/accesslint-diff/SKILL.md +81 -0
  4. package/bundled-skills/accesslint-scan/SKILL.md +47 -0
  5. package/bundled-skills/composition-patterns/SKILL.md +87 -0
  6. package/bundled-skills/composition-patterns/rules/_sections.md +29 -0
  7. package/bundled-skills/composition-patterns/rules/_template.md +24 -0
  8. package/bundled-skills/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  9. package/bundled-skills/composition-patterns/rules/architecture-compound-components.md +112 -0
  10. package/bundled-skills/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  11. package/bundled-skills/composition-patterns/rules/patterns-explicit-variants.md +100 -0
  12. package/bundled-skills/composition-patterns/rules/react19-no-forwardref.md +42 -0
  13. package/bundled-skills/composition-patterns/rules/state-context-interface.md +191 -0
  14. package/bundled-skills/composition-patterns/rules/state-decouple-implementation.md +113 -0
  15. package/bundled-skills/composition-patterns/rules/state-lift-state.md +125 -0
  16. package/bundled-skills/debugging-toolkit/SKILL.md +35 -0
  17. package/bundled-skills/deploy-to-vercel/SKILL.md +304 -0
  18. package/bundled-skills/deploy-to-vercel/resources/deploy-codex.sh +301 -0
  19. package/bundled-skills/deploy-to-vercel/resources/deploy.sh +301 -0
  20. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  21. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  22. package/bundled-skills/docs/maintainers/backups/README-2026-06-02.md +687 -0
  23. package/bundled-skills/docs/maintainers/repo-growth-seo.md +4 -4
  24. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  25. package/bundled-skills/docs/users/bundles.md +245 -1
  26. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  27. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  28. package/bundled-skills/docs/users/getting-started.md +1 -1
  29. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  30. package/bundled-skills/docs/users/plugins.md +21 -13
  31. package/bundled-skills/docs/users/specialized-plugin-roadmap.md +95 -0
  32. package/bundled-skills/docs/users/usage.md +4 -4
  33. package/bundled-skills/docs/users/visual-guide.md +4 -4
  34. package/bundled-skills/polis-protocol/SKILL.md +93 -0
  35. package/bundled-skills/python-development/SKILL.md +35 -0
  36. package/bundled-skills/radix-ui-design-system/SKILL.md +2 -2
  37. package/bundled-skills/react-native-skills/SKILL.md +120 -0
  38. package/bundled-skills/react-native-skills/rules/_sections.md +86 -0
  39. package/bundled-skills/react-native-skills/rules/_template.md +28 -0
  40. package/bundled-skills/react-native-skills/rules/animation-derived-value.md +53 -0
  41. package/bundled-skills/react-native-skills/rules/animation-gesture-detector-press.md +95 -0
  42. package/bundled-skills/react-native-skills/rules/animation-gpu-properties.md +65 -0
  43. package/bundled-skills/react-native-skills/rules/design-system-compound-components.md +66 -0
  44. package/bundled-skills/react-native-skills/rules/fonts-config-plugin.md +71 -0
  45. package/bundled-skills/react-native-skills/rules/imports-design-system-folder.md +68 -0
  46. package/bundled-skills/react-native-skills/rules/js-hoist-intl.md +61 -0
  47. package/bundled-skills/react-native-skills/rules/list-performance-callbacks.md +44 -0
  48. package/bundled-skills/react-native-skills/rules/list-performance-function-references.md +132 -0
  49. package/bundled-skills/react-native-skills/rules/list-performance-images.md +53 -0
  50. package/bundled-skills/react-native-skills/rules/list-performance-inline-objects.md +97 -0
  51. package/bundled-skills/react-native-skills/rules/list-performance-item-expensive.md +94 -0
  52. package/bundled-skills/react-native-skills/rules/list-performance-item-memo.md +82 -0
  53. package/bundled-skills/react-native-skills/rules/list-performance-item-types.md +104 -0
  54. package/bundled-skills/react-native-skills/rules/list-performance-virtualize.md +67 -0
  55. package/bundled-skills/react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
  56. package/bundled-skills/react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
  57. package/bundled-skills/react-native-skills/rules/navigation-native-navigators.md +188 -0
  58. package/bundled-skills/react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
  59. package/bundled-skills/react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
  60. package/bundled-skills/react-native-skills/rules/react-state-dispatcher.md +91 -0
  61. package/bundled-skills/react-native-skills/rules/react-state-fallback.md +56 -0
  62. package/bundled-skills/react-native-skills/rules/react-state-minimize.md +65 -0
  63. package/bundled-skills/react-native-skills/rules/rendering-no-falsy-and.md +74 -0
  64. package/bundled-skills/react-native-skills/rules/rendering-text-in-text-component.md +36 -0
  65. package/bundled-skills/react-native-skills/rules/scroll-position-no-state.md +82 -0
  66. package/bundled-skills/react-native-skills/rules/state-ground-truth.md +80 -0
  67. package/bundled-skills/react-native-skills/rules/ui-expo-image.md +66 -0
  68. package/bundled-skills/react-native-skills/rules/ui-image-gallery.md +104 -0
  69. package/bundled-skills/react-native-skills/rules/ui-measure-views.md +78 -0
  70. package/bundled-skills/react-native-skills/rules/ui-menus.md +174 -0
  71. package/bundled-skills/react-native-skills/rules/ui-native-modals.md +77 -0
  72. package/bundled-skills/react-native-skills/rules/ui-pressable.md +61 -0
  73. package/bundled-skills/react-native-skills/rules/ui-safe-area-scroll.md +65 -0
  74. package/bundled-skills/react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
  75. package/bundled-skills/react-native-skills/rules/ui-styling.md +87 -0
  76. package/bundled-skills/skill-issue/SKILL.md +73 -0
  77. package/bundled-skills/tdd-workflows/SKILL.md +35 -0
  78. package/bundled-skills/vercel-cli-with-tokens/SKILL.md +361 -0
  79. package/bundled-skills/vercel-optimize/CONTRIBUTING.md +41 -0
  80. package/bundled-skills/vercel-optimize/SKILL.md +331 -0
  81. package/bundled-skills/vercel-optimize/lib/auth-route.mjs +23 -0
  82. package/bundled-skills/vercel-optimize/lib/budget-summary.mjs +182 -0
  83. package/bundled-skills/vercel-optimize/lib/citations.mjs +139 -0
  84. package/bundled-skills/vercel-optimize/lib/cost-coverage.mjs +143 -0
  85. package/bundled-skills/vercel-optimize/lib/dedup-recs.mjs +325 -0
  86. package/bundled-skills/vercel-optimize/lib/deep-dive.mjs +350 -0
  87. package/bundled-skills/vercel-optimize/lib/display-labels.mjs +185 -0
  88. package/bundled-skills/vercel-optimize/lib/extract-claims.mjs +550 -0
  89. package/bundled-skills/vercel-optimize/lib/framework-support.mjs +67 -0
  90. package/bundled-skills/vercel-optimize/lib/gates/build-minutes-fanout.mjs +69 -0
  91. package/bundled-skills/vercel-optimize/lib/gates/cold-start.mjs +66 -0
  92. package/bundled-skills/vercel-optimize/lib/gates/contract.mjs +79 -0
  93. package/bundled-skills/vercel-optimize/lib/gates/cwv-poor.mjs +87 -0
  94. package/bundled-skills/vercel-optimize/lib/gates/external-api-slow.mjs +55 -0
  95. package/bundled-skills/vercel-optimize/lib/gates/hard-gates.mjs +73 -0
  96. package/bundled-skills/vercel-optimize/lib/gates/index.mjs +45 -0
  97. package/bundled-skills/vercel-optimize/lib/gates/isr-overrevalidation.mjs +62 -0
  98. package/bundled-skills/vercel-optimize/lib/gates/middleware-heavy.mjs +51 -0
  99. package/bundled-skills/vercel-optimize/lib/gates/observability-events-attribution.mjs +56 -0
  100. package/bundled-skills/vercel-optimize/lib/gates/platform-bot-protection.mjs +115 -0
  101. package/bundled-skills/vercel-optimize/lib/gates/platform-fluid-compute.mjs +83 -0
  102. package/bundled-skills/vercel-optimize/lib/gates/region-misconfig.mjs +64 -0
  103. package/bundled-skills/vercel-optimize/lib/gates/route-errors.mjs +80 -0
  104. package/bundled-skills/vercel-optimize/lib/gates/scanner-driven.mjs +122 -0
  105. package/bundled-skills/vercel-optimize/lib/gates/select-candidates.mjs +134 -0
  106. package/bundled-skills/vercel-optimize/lib/gates/slow-route.mjs +88 -0
  107. package/bundled-skills/vercel-optimize/lib/gates/types.d.ts +38 -0
  108. package/bundled-skills/vercel-optimize/lib/gates/uncached-route.mjs +93 -0
  109. package/bundled-skills/vercel-optimize/lib/gates/usage-spike-triage.mjs +121 -0
  110. package/bundled-skills/vercel-optimize/lib/grade-recommendation.mjs +155 -0
  111. package/bundled-skills/vercel-optimize/lib/impact-label.mjs +126 -0
  112. package/bundled-skills/vercel-optimize/lib/impact-magnitude.mjs +60 -0
  113. package/bundled-skills/vercel-optimize/lib/investigation-brief.mjs +610 -0
  114. package/bundled-skills/vercel-optimize/lib/observation-safety.mjs +174 -0
  115. package/bundled-skills/vercel-optimize/lib/project-facts.mjs +99 -0
  116. package/bundled-skills/vercel-optimize/lib/queries.mjs +315 -0
  117. package/bundled-skills/vercel-optimize/lib/reconcile-candidates.mjs +372 -0
  118. package/bundled-skills/vercel-optimize/lib/render-report.mjs +955 -0
  119. package/bundled-skills/vercel-optimize/lib/repo-root.mjs +86 -0
  120. package/bundled-skills/vercel-optimize/lib/route-normalize.mjs +220 -0
  121. package/bundled-skills/vercel-optimize/lib/sanitizers/bot-protection-certainty.mjs +38 -0
  122. package/bundled-skills/vercel-optimize/lib/sanitizers/cache-tag-invalidation-certainty.mjs +30 -0
  123. package/bundled-skills/vercel-optimize/lib/sanitizers/count-correct.mjs +52 -0
  124. package/bundled-skills/vercel-optimize/lib/sanitizers/function-duration-invocations.mjs +38 -0
  125. package/bundled-skills/vercel-optimize/lib/sanitizers/index.mjs +79 -0
  126. package/bundled-skills/vercel-optimize/lib/sanitizers/middleware-conflict.mjs +36 -0
  127. package/bundled-skills/vercel-optimize/lib/sanitizers/missing-citation.mjs +16 -0
  128. package/bundled-skills/vercel-optimize/lib/sanitizers/pre-release.mjs +74 -0
  129. package/bundled-skills/vercel-optimize/lib/sanitizers/rate-limit.mjs +67 -0
  130. package/bundled-skills/vercel-optimize/lib/sanitizers/rendering-mode-mislabel.mjs +38 -0
  131. package/bundled-skills/vercel-optimize/lib/sanitizers/undeclared-dep.mjs +78 -0
  132. package/bundled-skills/vercel-optimize/lib/sanitizers/vercel-directive-strip.mjs +37 -0
  133. package/bundled-skills/vercel-optimize/lib/sanitizers/window-units.mjs +32 -0
  134. package/bundled-skills/vercel-optimize/lib/scanners/cache-components-suspense-dedupe.mjs +109 -0
  135. package/bundled-skills/vercel-optimize/lib/scanners/edge-heavy-import.mjs +94 -0
  136. package/bundled-skills/vercel-optimize/lib/scanners/force-dynamic.mjs +42 -0
  137. package/bundled-skills/vercel-optimize/lib/scanners/headers-in-page.mjs +44 -0
  138. package/bundled-skills/vercel-optimize/lib/scanners/index.mjs +35 -0
  139. package/bundled-skills/vercel-optimize/lib/scanners/large-static-asset.mjs +92 -0
  140. package/bundled-skills/vercel-optimize/lib/scanners/max-age-without-s-maxage.mjs +42 -0
  141. package/bundled-skills/vercel-optimize/lib/scanners/middleware-broad-matcher.mjs +55 -0
  142. package/bundled-skills/vercel-optimize/lib/scanners/missing-cache-headers.mjs +90 -0
  143. package/bundled-skills/vercel-optimize/lib/scanners/prisma-include-tree.mjs +42 -0
  144. package/bundled-skills/vercel-optimize/lib/scanners/region-pin-in-config.mjs +88 -0
  145. package/bundled-skills/vercel-optimize/lib/scanners/source-maps-production.mjs +36 -0
  146. package/bundled-skills/vercel-optimize/lib/scanners/sveltekit-prerender-missing.mjs +43 -0
  147. package/bundled-skills/vercel-optimize/lib/scanners/turbo-force-bypass.mjs +129 -0
  148. package/bundled-skills/vercel-optimize/lib/scanners/unoptimized-image.mjs +113 -0
  149. package/bundled-skills/vercel-optimize/lib/scanners/use-cache-date-stamp.mjs +106 -0
  150. package/bundled-skills/vercel-optimize/lib/support-topics.mjs +355 -0
  151. package/bundled-skills/vercel-optimize/lib/throttle.mjs +273 -0
  152. package/bundled-skills/vercel-optimize/lib/util.mjs +17 -0
  153. package/bundled-skills/vercel-optimize/lib/vercel.mjs +784 -0
  154. package/bundled-skills/vercel-optimize/lib/verify-claim.mjs +1296 -0
  155. package/bundled-skills/vercel-optimize/lib/workspace-resolver.mjs +521 -0
  156. package/bundled-skills/vercel-optimize/references/candidates.md +176 -0
  157. package/bundled-skills/vercel-optimize/references/data-collection.md +218 -0
  158. package/bundled-skills/vercel-optimize/references/docs-library.json +683 -0
  159. package/bundled-skills/vercel-optimize/references/doctrine.md +105 -0
  160. package/bundled-skills/vercel-optimize/references/observability-plus.md +108 -0
  161. package/bundled-skills/vercel-optimize/references/playbooks/README.md +53 -0
  162. package/bundled-skills/vercel-optimize/references/playbooks/ai-application.md +32 -0
  163. package/bundled-skills/vercel-optimize/references/playbooks/api-service.md +30 -0
  164. package/bundled-skills/vercel-optimize/references/playbooks/content-site.md +30 -0
  165. package/bundled-skills/vercel-optimize/references/playbooks/ecommerce.md +30 -0
  166. package/bundled-skills/vercel-optimize/references/playbooks/marketing.md +30 -0
  167. package/bundled-skills/vercel-optimize/references/playbooks/saas.md +31 -0
  168. package/bundled-skills/vercel-optimize/references/playbooks/sveltekit.md +75 -0
  169. package/bundled-skills/vercel-optimize/references/recommendations.md +203 -0
  170. package/bundled-skills/vercel-optimize/references/scanner-patterns.md +251 -0
  171. package/bundled-skills/vercel-optimize/references/scoring.md +205 -0
  172. package/bundled-skills/vercel-optimize/references/support-topics/README.md +46 -0
  173. package/bundled-skills/vercel-optimize/references/support-topics/astro-edge-middleware-scope.md +22 -0
  174. package/bundled-skills/vercel-optimize/references/support-topics/astro-output-mode-and-isr.md +22 -0
  175. package/bundled-skills/vercel-optimize/references/support-topics/auth-preserving-parallelization.md +22 -0
  176. package/bundled-skills/vercel-optimize/references/support-topics/bot-protection-product-guardrails.md +22 -0
  177. package/bundled-skills/vercel-optimize/references/support-topics/build-minutes-monorepo-fanout.md +23 -0
  178. package/bundled-skills/vercel-optimize/references/support-topics/cache-components-static-shell-boundaries.md +22 -0
  179. package/bundled-skills/vercel-optimize/references/support-topics/cache-components-suspense-dedupe-pitfall.md +23 -0
  180. package/bundled-skills/vercel-optimize/references/support-topics/cdn-cache-auth-safety.md +22 -0
  181. package/bundled-skills/vercel-optimize/references/support-topics/cold-start-initialization-bundle.md +22 -0
  182. package/bundled-skills/vercel-optimize/references/support-topics/core-web-vitals-client-bottlenecks.md +22 -0
  183. package/bundled-skills/vercel-optimize/references/support-topics/database-egress-pooling-region.md +22 -0
  184. package/bundled-skills/vercel-optimize/references/support-topics/dynamic-rendering-traps.md +22 -0
  185. package/bundled-skills/vercel-optimize/references/support-topics/external-api-critical-path-platform.md +22 -0
  186. package/bundled-skills/vercel-optimize/references/support-topics/external-api-critical-path.md +22 -0
  187. package/bundled-skills/vercel-optimize/references/support-topics/fast-data-transfer-payloads.md +22 -0
  188. package/bundled-skills/vercel-optimize/references/support-topics/fluid-compute-caveats.md +22 -0
  189. package/bundled-skills/vercel-optimize/references/support-topics/function-duration-io-and-after.md +22 -0
  190. package/bundled-skills/vercel-optimize/references/support-topics/function-invocation-reduction.md +22 -0
  191. package/bundled-skills/vercel-optimize/references/support-topics/function-region-misconfiguration-ttfb.md +23 -0
  192. package/bundled-skills/vercel-optimize/references/support-topics/image-optimization-cost-control.md +22 -0
  193. package/bundled-skills/vercel-optimize/references/support-topics/isr-revalidation-static-generation.md +22 -0
  194. package/bundled-skills/vercel-optimize/references/support-topics/middleware-proxy-edge-cost.md +22 -0
  195. package/bundled-skills/vercel-optimize/references/support-topics/next-fetch-revalidate-floor.md +22 -0
  196. package/bundled-skills/vercel-optimize/references/support-topics/next-font-cls-self-hosting.md +23 -0
  197. package/bundled-skills/vercel-optimize/references/support-topics/next-heavy-ui-lazy-load-boundaries.md +23 -0
  198. package/bundled-skills/vercel-optimize/references/support-topics/next-image-lcp-preload-sizes.md +23 -0
  199. package/bundled-skills/vercel-optimize/references/support-topics/next-route-handler-get-cache-defaults.md +22 -0
  200. package/bundled-skills/vercel-optimize/references/support-topics/next-script-third-party-strategy.md +23 -0
  201. package/bundled-skills/vercel-optimize/references/support-topics/nextjs-version-cache-semantics.md +22 -0
  202. package/bundled-skills/vercel-optimize/references/support-topics/not-found-catchall-request-waste.md +23 -0
  203. package/bundled-skills/vercel-optimize/references/support-topics/nuxt-route-rules-cache-isr.md +22 -0
  204. package/bundled-skills/vercel-optimize/references/support-topics/observability-events-cost-attribution.md +22 -0
  205. package/bundled-skills/vercel-optimize/references/support-topics/post-response-work-waituntil.md +22 -0
  206. package/bundled-skills/vercel-optimize/references/support-topics/route-error-durable-offload.md +22 -0
  207. package/bundled-skills/vercel-optimize/references/support-topics/route-error-runtime-limits.md +22 -0
  208. package/bundled-skills/vercel-optimize/references/support-topics/runtime-cache-reusable-data.md +22 -0
  209. package/bundled-skills/vercel-optimize/references/support-topics/sveltekit-isr-prerender-safety.md +22 -0
  210. package/bundled-skills/vercel-optimize/references/support-topics/sveltekit-split-cold-start-tradeoff.md +22 -0
  211. package/bundled-skills/vercel-optimize/references/support-topics/usage-spike-triage.md +22 -0
  212. package/bundled-skills/vercel-optimize/references/support-topics/use-cache-date-stamp-isr-write-amplifier.md +23 -0
  213. package/bundled-skills/vercel-optimize/references/support-topics/use-cache-remote-shared-origin-data.md +22 -0
  214. package/bundled-skills/vercel-optimize/references/support-topics/workflow-resumable-stream-routes.md +23 -0
  215. package/bundled-skills/vercel-optimize/references/verification.md +102 -0
  216. package/bundled-skills/vercel-optimize/references/voice.md +76 -0
  217. package/bundled-skills/vercel-optimize/scripts/budget-summary.mjs +56 -0
  218. package/bundled-skills/vercel-optimize/scripts/build-docs.mjs +74 -0
  219. package/bundled-skills/vercel-optimize/scripts/check-citations.mjs +81 -0
  220. package/bundled-skills/vercel-optimize/scripts/check-docs-fresh.mjs +93 -0
  221. package/bundled-skills/vercel-optimize/scripts/collect-signals.mjs +576 -0
  222. package/bundled-skills/vercel-optimize/scripts/collect-sub-agent-outputs.mjs +296 -0
  223. package/bundled-skills/vercel-optimize/scripts/deep-dive.mjs +319 -0
  224. package/bundled-skills/vercel-optimize/scripts/gate-investigations.mjs +166 -0
  225. package/bundled-skills/vercel-optimize/scripts/merge-signals.mjs +192 -0
  226. package/bundled-skills/vercel-optimize/scripts/prepare-investigation-brief.mjs +231 -0
  227. package/bundled-skills/vercel-optimize/scripts/reconcile-candidates.mjs +62 -0
  228. package/bundled-skills/vercel-optimize/scripts/render-report.mjs +437 -0
  229. package/bundled-skills/vercel-optimize/scripts/scan-codebase.mjs +313 -0
  230. package/bundled-skills/vercel-optimize/scripts/verify-and-regen.mjs +346 -0
  231. package/bundled-skills/vercel-optimize/scripts/verify-finding.mjs +19 -0
  232. package/bundled-skills/vercel-react-view-transitions/SKILL.md +327 -0
  233. package/bundled-skills/vercel-react-view-transitions/references/css-recipes.md +242 -0
  234. package/bundled-skills/vercel-react-view-transitions/references/implementation.md +182 -0
  235. package/bundled-skills/vercel-react-view-transitions/references/nextjs.md +176 -0
  236. package/bundled-skills/vercel-react-view-transitions/references/patterns.md +262 -0
  237. package/package.json +1 -1
  238. package/skills_index.json +312 -0
@@ -0,0 +1,576 @@
1
+ #!/usr/bin/env node
2
+ // Emits signals.json: Vercel CLI capability probe + project config + plan +
3
+ // usage + codebase stack + metric queries. Status → stderr, JSON → stdout.
4
+ // Degrades gracefully when capabilities are missing.
5
+
6
+ import {
7
+ checkCliVersion,
8
+ checkAuth,
9
+ resolveProjectId,
10
+ resolveCommandScope,
11
+ hasObservabilityPlus,
12
+ checkObservabilityPlusConfiguration,
13
+ getMetricsSchema,
14
+ getProjectConfig,
15
+ getAccountPlan,
16
+ getContract,
17
+ getUsage,
18
+ filterUsageByProject,
19
+ inferPlan,
20
+ queryMetric,
21
+ detectStack,
22
+ redactSensitiveText,
23
+ } from '../lib/vercel.mjs';
24
+ import { classifyFrameworkSupport } from '../lib/framework-support.mjs';
25
+ import { QUERIES, TIME_WINDOW, normalizerFor } from '../lib/queries.mjs';
26
+
27
+ const SCHEMA_VERSION = '1.2';
28
+
29
+ const log = (...args) => console.error('[collect-signals]', ...args);
30
+
31
+ function parseArgs(argv) {
32
+ let explicitProjectId = null;
33
+ let continueWithoutObservability = process.env.VERCEL_OPTIMIZE_CONTINUE_WITHOUT_OBSERVABILITY === '1';
34
+ let continueUnsupportedFramework = process.env.VERCEL_OPTIMIZE_CONTINUE_UNSUPPORTED_FRAMEWORK === '1';
35
+
36
+ for (const arg of argv) {
37
+ if (arg === '--continue-without-observability') {
38
+ continueWithoutObservability = true;
39
+ continue;
40
+ }
41
+ if (arg === '--continue-unsupported-framework') {
42
+ continueUnsupportedFramework = true;
43
+ continue;
44
+ }
45
+ if (arg.startsWith('--')) {
46
+ throw new Error(`UNKNOWN_ARG: ${arg}`);
47
+ }
48
+ if (!explicitProjectId) {
49
+ explicitProjectId = arg;
50
+ continue;
51
+ }
52
+ throw new Error(`UNKNOWN_ARG: ${arg}`);
53
+ }
54
+
55
+ return { explicitProjectId, continueWithoutObservability, continueUnsupportedFramework };
56
+ }
57
+
58
+ async function main() {
59
+ const { explicitProjectId, continueWithoutObservability, continueUnsupportedFramework } = parseArgs(process.argv.slice(2));
60
+
61
+ log('checking Vercel CLI version…');
62
+ const cli = await checkCliVersion();
63
+ log(`vercel CLI v${cli.join('.')} OK`);
64
+
65
+ log('checking auth…');
66
+ await checkAuth();
67
+ log('auth OK');
68
+
69
+ log('resolving project id…');
70
+ const project = await resolveProjectId(explicitProjectId);
71
+ if (!project) {
72
+ throw new Error(
73
+ 'NO_PROJECT_ID: pass one as argv, set VERCEL_PROJECT_ID, or run `vercel link` in this directory.'
74
+ );
75
+ }
76
+ log(`project link resolved (source=${project.source}; teamScope=${project.orgId ? 'yes' : 'no'})`);
77
+
78
+ if (!project.orgId) {
79
+ throw new Error('PROJECT_SCOPE_UNRESOLVED: the project was resolved without an owner account. Ask the user which Vercel team or personal scope owns the project, then rerun from a linked app directory or set VERCEL_PROJECT_ID with VERCEL_ORG_ID for that scope.');
80
+ }
81
+
82
+ log('checking framework support…');
83
+ const stack = await detectStack();
84
+ const frameworkSupport = classifyFrameworkSupport(stack);
85
+ log(`framework=${stack.framework}@${stack.frameworkVersion ?? '?'} support=${frameworkSupport.status}`);
86
+
87
+ if (!frameworkSupport.ok && !continueUnsupportedFramework) {
88
+ writeOutput({
89
+ schemaVersion: SCHEMA_VERSION,
90
+ collectedAt: new Date().toISOString(),
91
+ timeWindow: TIME_WINDOW,
92
+ projectId: project.projectId,
93
+ orgId: project.orgId,
94
+ projectIdSource: project.source,
95
+ commandScope: null,
96
+ frameworkSupport,
97
+ frameworkSupportBlocker: frameworkSupport.blocker,
98
+ frameworkSupportDetail: frameworkSupport.detail,
99
+ observabilityPlus: null,
100
+ observabilityPlusPreflight: null,
101
+ observabilityPlusUsable: null,
102
+ observabilityPlusBlocker: null,
103
+ observabilityPlusBlockerDetail: null,
104
+ plan: {
105
+ plan: 'uncertain',
106
+ reason: 'not collected before unsupported-framework confirmation',
107
+ },
108
+ project: null,
109
+ contract: null,
110
+ usage: null,
111
+ usageScope: null,
112
+ usageTeamTotal: null,
113
+ usageError: 'NOT_COLLECTED_UNSUPPORTED_FRAMEWORK',
114
+ stack,
115
+ metrics: {},
116
+ metricsSchema: null,
117
+ }, { usable: true, blocker: null, detail: 'Observability Plus was not checked.' }, frameworkSupport);
118
+ return;
119
+ }
120
+
121
+ if (!frameworkSupport.ok && continueUnsupportedFramework) {
122
+ log('continuing after unsupported framework blocker because --continue-unsupported-framework was set');
123
+ }
124
+
125
+ log('resolving Vercel CLI command scope…');
126
+ const commandScope = await resolveCommandScope(project);
127
+ if (!commandScope.ok) {
128
+ throw new Error(`SCOPE_UNRESOLVED: ${commandScope.detail} Run \`vercel switch <team>\` or re-link with \`vercel link --yes --project <project-name-or-id> --team <team-slug>\`.`);
129
+ }
130
+ const scope = commandScope.cliScope || undefined;
131
+ log(`command scope resolved (source=${commandScope.source}; scoped=${scope ? 'yes' : 'no'})`);
132
+
133
+ log('validating linked project belongs to the resolved scope…');
134
+ const projectCfg = await getProjectConfig(project.projectId, project.orgId);
135
+ const projectScope = validateProjectScope(projectCfg, project);
136
+ if (!projectScope.ok) {
137
+ throw new Error(`PROJECT_SCOPE_MISMATCH: ${projectScope.detail} Ask the user to confirm the exact Vercel project and team/personal scope, then rerun after \`vercel link --yes --project <project-name-or-id> --team <team-slug>\` or after setting both VERCEL_PROJECT_ID and VERCEL_ORG_ID for the intended scope.`);
138
+ }
139
+ log(`project scope verified (source=${projectScope.source})`);
140
+
141
+ log('checking Observability Plus configuration…');
142
+ const observabilityPlusConfig = await checkObservabilityPlusConfiguration({
143
+ orgId: project.orgId,
144
+ projectId: project.projectId,
145
+ });
146
+ log(`observabilityPlusPreflight=${observabilityPlusConfig.access === true ? 'enabled' : observabilityPlusConfig.blocker ?? 'unknown'} (${observabilityPlusConfig.source})`);
147
+
148
+ let oplus = observabilityPlusConfig.access === true;
149
+ if (observabilityPlusConfig.access == null) {
150
+ log('Observability Plus configuration preflight inconclusive; falling back to metrics schema probe…');
151
+ oplus = await hasObservabilityPlus(scope);
152
+ }
153
+ log(`observabilityPlus=${oplus}`);
154
+
155
+ const schema = oplus ? await getMetricsSchema(scope) : null;
156
+ if (oplus && schema) {
157
+ const count = Array.isArray(schema) ? schema.length : (schema.metrics?.length ?? 0);
158
+ log(`metric catalog: ${count} metrics available`);
159
+ }
160
+
161
+ // Check one cheap metric before pulling slower project context. If this fails,
162
+ // the orchestrator can ask the user immediately instead of waiting on billing.
163
+ let metrics = {};
164
+ let metricsCanaryOk = false;
165
+ if (oplus) {
166
+ log(`checking Observability Plus metrics access (window=${TIME_WINDOW})…`);
167
+ const t0 = Date.now();
168
+ const canary = await queryMetric('vercel.request.count', {
169
+ aggregation: 'sum',
170
+ since: TIME_WINDOW,
171
+ limit: 1,
172
+ scope,
173
+ });
174
+ metricsCanaryOk = !!canary?.ok;
175
+ if (!metricsCanaryOk) {
176
+ metrics = {
177
+ observabilityPlusCanary: {
178
+ ...canary,
179
+ metricId: 'vercel.request.count',
180
+ aggregation: 'sum',
181
+ },
182
+ };
183
+ log(`metrics access check failed: ${canary?.code ?? 'unknown'} — skipping full metrics fan-out`);
184
+ } else {
185
+ log(`metrics access check passed in ${Date.now() - t0}ms`);
186
+ }
187
+ } else {
188
+ log('skipping metric queries (Observability Plus preflight did not confirm access)');
189
+ }
190
+
191
+ let oplusDiag = observabilityPlusConfig.access === false
192
+ ? {
193
+ usable: false,
194
+ blocker: observabilityPlusConfig.blocker,
195
+ detail: observabilityPlusConfig.detail,
196
+ }
197
+ : (metricsCanaryOk
198
+ ? { usable: true, blocker: null, detail: 'Observability Plus metrics access check passed.' }
199
+ : diagnoseObservabilityPlus(metrics, oplus));
200
+
201
+ if (!oplusDiag.usable && !continueWithoutObservability) {
202
+ writeOutput({
203
+ schemaVersion: SCHEMA_VERSION,
204
+ collectedAt: new Date().toISOString(),
205
+ timeWindow: TIME_WINDOW,
206
+ projectId: project.projectId,
207
+ orgId: project.orgId,
208
+ projectIdSource: project.source,
209
+ commandScope,
210
+ observabilityPlus: oplus,
211
+ observabilityPlusPreflight: observabilityPlusConfig,
212
+ observabilityPlusUsable: oplusDiag.usable,
213
+ observabilityPlusBlocker: oplusDiag.blocker,
214
+ observabilityPlusBlockerDetail: oplusDiag.detail,
215
+ frameworkSupport,
216
+ frameworkSupportBlocker: frameworkSupport.blocker,
217
+ frameworkSupportDetail: frameworkSupport.detail,
218
+ plan: {
219
+ plan: 'uncertain',
220
+ reason: 'not collected before Observability Plus blocker confirmation',
221
+ },
222
+ project: projectCfg,
223
+ contract: null,
224
+ usage: null,
225
+ usageScope: null,
226
+ usageTeamTotal: null,
227
+ usageError: 'NOT_COLLECTED_OBSERVABILITY_BLOCKED',
228
+ stack: null,
229
+ metrics,
230
+ metricsSchema: schema,
231
+ }, oplusDiag);
232
+ return;
233
+ }
234
+
235
+ if (!oplusDiag.usable && continueWithoutObservability) {
236
+ log('continuing after Observability Plus blocker because --continue-without-observability was set');
237
+ }
238
+
239
+ log('pulling account plan + contract + usage in parallel…');
240
+ const [accountPlan, contract, usageResult] = await Promise.all([
241
+ getAccountPlan(project.orgId || scope),
242
+ getContract(scope),
243
+ getUsage({ days: 14, scope }),
244
+ ]);
245
+
246
+ let usage = null;
247
+ let usageContextMismatch = false;
248
+ let usageTotalCost = null;
249
+ let usageScope = 'team';
250
+ let usageTeamTotal = null;
251
+ if (usageResult?.ok) {
252
+ usage = usageResult.data;
253
+ const contractContext = contract?.context;
254
+ if (usage?.context && contractContext && usage.context !== contractContext) {
255
+ usageContextMismatch = true;
256
+ log(`usage: WARNING context mismatch — returned context=${usage.context} but project team=${contractContext}; treating usage as unavailable for this project`);
257
+ usage = null;
258
+ } else {
259
+ // Capture team total pre-filter so the report can label "this project vs team-wide" honestly.
260
+ usageTeamTotal = sumUsageCosts(usage);
261
+ const filterResult = filterUsageByProject(usage, project.projectId, projectCfg?.name);
262
+ if (filterResult.matched) {
263
+ usage = filterResult.filtered;
264
+ usageScope = 'project';
265
+ usageTotalCost = sumUsageCosts(usage);
266
+ log(`usage: filtered to project — ~$${usageTotalCost.toFixed(2)} (team-wide ~$${usageTeamTotal.toFixed(2)}; unattributed ~$${filterResult.unattributedTotal.toFixed(2)})`);
267
+ } else {
268
+ usageTotalCost = usageTeamTotal;
269
+ log(`usage: ~$${usageTotalCost.toFixed(2)} billed across services (team-wide — no per-project usage rows matched the linked project; report will label this team-wide)`);
270
+ }
271
+ }
272
+ } else {
273
+ log(`usage: unavailable (${usageResult?.code ?? 'unknown'}) — degrading to scanner+metrics-only mode`);
274
+ }
275
+
276
+ const planInfo = inferPlan(contract, { accountPlan, usageTotalCost });
277
+ log(`plan=${planInfo.plan} (${planInfo.reason})`);
278
+
279
+ if (projectCfg?.error) {
280
+ log(`project config: failed (${projectCfg.error}) — gates that need it will skip`);
281
+ }
282
+
283
+ log(`stack: ${stack.framework}@${stack.frameworkVersion ?? '?'} ${stack.hasAppRouter ? 'app-router' : ''}${stack.hasPagesRouter ? ' pages-router' : ''}${stack.orm !== 'none' ? ` orm=${stack.orm}` : ''}`);
284
+
285
+ // Each query is wrapped; one failure degrades only that metric.
286
+ if (oplus && metricsCanaryOk) {
287
+ log(`querying observability metrics (${QUERIES.length} metrics in parallel)…`);
288
+ const t0 = Date.now();
289
+ metrics = await collectMetrics(scope);
290
+ const wallMs = Date.now() - t0;
291
+ const counts = Object.fromEntries(
292
+ Object.entries(metrics).map(([k, v]) => {
293
+ if (!v) return [k, 'null'];
294
+ if (!v.ok) return [k, `err:${v.code}`];
295
+ const rows = Array.isArray(v.rows) ? v.rows.length : 0;
296
+ return [k, `${rows} rows`];
297
+ })
298
+ );
299
+ log(`metrics collected in ${wallMs}ms: ${JSON.stringify(counts)}`);
300
+ }
301
+
302
+ // The `vercel metrics schema` probe alone is NOT a reliable usability signal:
303
+ // it can return OK while per-route queries fail with payment_required (metrics
304
+ // unavailable for the team) or FORBIDDEN (auth-scope mismatch). Diagnose AFTER
305
+ // running queries by counting failure codes so the orchestrator can PAUSE and
306
+ // surface the choice before falling back to scanner-only mode.
307
+ oplusDiag = observabilityPlusConfig.access === false
308
+ ? {
309
+ usable: false,
310
+ blocker: observabilityPlusConfig.blocker,
311
+ detail: observabilityPlusConfig.detail,
312
+ }
313
+ : diagnoseObservabilityPlus(metrics, oplus);
314
+
315
+
316
+ const output = {
317
+ schemaVersion: SCHEMA_VERSION,
318
+ collectedAt: new Date().toISOString(),
319
+ timeWindow: TIME_WINDOW,
320
+ projectId: project.projectId,
321
+ orgId: project.orgId,
322
+ projectIdSource: project.source,
323
+ commandScope,
324
+ observabilityPlus: oplus,
325
+ observabilityPlusPreflight: observabilityPlusConfig,
326
+ observabilityPlusUsable: oplusDiag.usable,
327
+ observabilityPlusBlocker: oplusDiag.blocker,
328
+ observabilityPlusBlockerDetail: oplusDiag.detail,
329
+ frameworkSupport,
330
+ frameworkSupportBlocker: frameworkSupport.blocker,
331
+ frameworkSupportDetail: frameworkSupport.detail,
332
+ plan: planInfo,
333
+ project: projectCfg,
334
+ contract,
335
+ usage,
336
+ usageScope,
337
+ usageTeamTotal,
338
+ usageError: usageResult?.ok
339
+ ? (usageContextMismatch ? 'USAGE_CONTEXT_MISMATCH' : null)
340
+ : (usageResult?.code ?? 'UNKNOWN'),
341
+ stack,
342
+ metrics,
343
+ metricsSchema: schema,
344
+ };
345
+
346
+ writeOutput(output, oplusDiag);
347
+ }
348
+
349
+ function writeOutput(output, oplusDiag, frameworkSupport = output.frameworkSupport) {
350
+ if (frameworkSupport?.blocker) {
351
+ log(`⚠ Framework is not supported for metric-backed route-to-file optimization: ${frameworkSupport.detail}`);
352
+ log(' The orchestrator should PAUSE and ask whether to continue with a limited platform/scanner audit.');
353
+ }
354
+ if (!oplusDiag.usable) {
355
+ log(`⚠ Observability Plus is NOT usable on this project: blocker=${oplusDiag.blocker} (${oplusDiag.detail})`);
356
+ log(' The orchestrator should PAUSE and follow the blocker-specific remediation before proceeding.');
357
+ }
358
+
359
+ process.stdout.write(JSON.stringify(output, null, 2) + '\n');
360
+ log('done');
361
+ }
362
+
363
+ function validateProjectScope(projectCfg, project) {
364
+ if (!projectCfg || projectCfg.error) {
365
+ return {
366
+ ok: false,
367
+ source: 'project-api',
368
+ detail: `The resolved account could not read the resolved project (project API error=${projectCfg?.error ?? 'unknown'}).`,
369
+ };
370
+ }
371
+
372
+ if (projectCfg.id && String(projectCfg.id) !== String(project.projectId)) {
373
+ return {
374
+ ok: false,
375
+ source: 'project-api',
376
+ detail: 'The project API returned a different project than the collector resolved from the link or environment.',
377
+ };
378
+ }
379
+
380
+ const ownerId = firstString(
381
+ projectCfg.accountId,
382
+ projectCfg.orgId,
383
+ projectCfg.ownerId,
384
+ projectCfg.teamId,
385
+ projectCfg.team?.id,
386
+ projectCfg.account?.id,
387
+ projectCfg.owner?.id,
388
+ );
389
+ if (ownerId && project.orgId && String(ownerId) !== String(project.orgId)) {
390
+ return {
391
+ ok: false,
392
+ source: 'project-api',
393
+ detail: 'The project API returned an owner account that differs from the collector-resolved account.',
394
+ };
395
+ }
396
+
397
+ return {
398
+ ok: true,
399
+ source: ownerId ? 'project-api-owner' : 'project-api-readable',
400
+ };
401
+ }
402
+
403
+ function firstString(...values) {
404
+ return values.find((value) => typeof value === 'string' && value.trim() !== '') ?? null;
405
+ }
406
+
407
+ async function collectMetrics(scope) {
408
+ const results = await Promise.all(
409
+ QUERIES.map(async (entry) => {
410
+ const r = await queryMetric(entry.metricId, {
411
+ aggregation: entry.aggregation,
412
+ groupBy: entry.groupBy,
413
+ filter: entry.filter,
414
+ since: TIME_WINDOW,
415
+ limit: entry.limit,
416
+ scope,
417
+ });
418
+ return [entry, r];
419
+ })
420
+ );
421
+
422
+ const out = {};
423
+ for (const [entry, result] of results) {
424
+ out[entry.id] = enrichEntry(entry, result);
425
+ }
426
+ return out;
427
+ }
428
+
429
+ function enrichEntry(entry, result) {
430
+ if (!result?.ok) {
431
+ return {
432
+ ...result,
433
+ metricId: entry.metricId,
434
+ aggregation: entry.aggregation,
435
+ groupBy: entry.groupBy,
436
+ };
437
+ }
438
+ const normalize = normalizerFor(entry);
439
+ const { rows } = normalize(result.data);
440
+ return {
441
+ ...result,
442
+ rows,
443
+ metricId: entry.metricId,
444
+ aggregation: entry.aggregation,
445
+ groupBy: entry.groupBy,
446
+ };
447
+ }
448
+
449
+ // `vercel usage --format json` shape is documented but not stable across CLI
450
+ // versions; try several roots, return null if none match.
451
+ function sumUsageCosts(usage) {
452
+ if (!usage) return null;
453
+ if (typeof usage.totalCost === 'number') return usage.totalCost;
454
+ if (typeof usage.totals?.billedCost === 'number') return usage.totals.billedCost;
455
+ if (Array.isArray(usage.services)) {
456
+ return usage.services.reduce((s, x) => s + (x.billedCost ?? x.cost ?? 0), 0);
457
+ }
458
+ if (Array.isArray(usage.breakdown?.data)) {
459
+ return usage.breakdown.data.reduce((s, d) => {
460
+ if (Array.isArray(d.services)) {
461
+ return s + d.services.reduce((ss, x) => ss + (x.billedCost ?? x.cost ?? 0), 0);
462
+ }
463
+ return s + (d.billedCost ?? d.cost ?? 0);
464
+ }, 0);
465
+ }
466
+ return null;
467
+ }
468
+
469
+ // Returns { usable, blocker, detail }. `blocker` enum:
470
+ // null | 'no_oplus_probe' | 'project_disabled' | 'payment_required' |
471
+ // 'forbidden' | 'daily_quota_exceeded' | 'project_not_found' |
472
+ // 'not_linked' | 'all_failed_other' | 'no_traffic'
473
+ export function diagnoseObservabilityPlus(metrics, oplusProbe) {
474
+ if (!oplusProbe) {
475
+ return {
476
+ usable: false,
477
+ blocker: 'no_oplus_probe',
478
+ detail: 'vercel metrics schema returned non-OK; the team does not have Observability Plus enabled.',
479
+ };
480
+ }
481
+
482
+ const entries = Object.values(metrics);
483
+ if (entries.length === 0) {
484
+ return { usable: false, blocker: 'no_oplus_probe', detail: 'No metrics were attempted.' };
485
+ }
486
+
487
+ const failures = entries.filter((m) => m && m.ok === false);
488
+ const successes = entries.filter((m) => m && m.ok !== false);
489
+
490
+ if (successes.length === 0) {
491
+ const codeCounts = new Map();
492
+ for (const f of failures) {
493
+ const code = String(f.code ?? 'unknown').toLowerCase();
494
+ codeCounts.set(code, (codeCounts.get(code) ?? 0) + 1);
495
+ }
496
+ const top = [...codeCounts.entries()].sort((a, b) => b[1] - a[1])[0];
497
+ const topCode = top?.[0] ?? 'unknown';
498
+ if (/daily_quota_exceeded/.test(topCode)) {
499
+ return {
500
+ usable: false,
501
+ blocker: 'daily_quota_exceeded',
502
+ detail: `${top[1]}/${entries.length} metric queries hit the daily Observability query limit. Retry after the next UTC midnight reset.`,
503
+ };
504
+ }
505
+ if (/payment_required/.test(topCode)) {
506
+ const text = failures
507
+ .map((f) => `${f.message ?? ''}\n${f.stderr ?? ''}`)
508
+ .join('\n')
509
+ .toLowerCase();
510
+ if (
511
+ /subscription to observability plus[\s\S]{0,160}required/.test(text) ||
512
+ /observability plus[\s\S]{0,160}not enabled/.test(text)
513
+ ) {
514
+ return {
515
+ usable: false,
516
+ blocker: 'no_oplus_probe',
517
+ detail: `${top[1]}/${entries.length} metric queries need route-level Observability Plus data. Enable Observability Plus, then re-run the metric-backed audit.`,
518
+ };
519
+ }
520
+ return {
521
+ usable: false,
522
+ blocker: 'payment_required',
523
+ detail: `${top[1]}/${entries.length} metric queries returned payment_required. Route-level metrics were recognized for this team, but these queries are not usable. Check the team's Observability Plus subscription or event quota.`,
524
+ };
525
+ }
526
+ if (/forbidden|not_authorized|403/.test(topCode)) {
527
+ return {
528
+ usable: false,
529
+ blocker: 'forbidden',
530
+ detail: `${top[1]}/${entries.length} metric queries returned FORBIDDEN. Auth-scope mismatch — likely logged in to the wrong team (run \`vercel switch\`).`,
531
+ };
532
+ }
533
+ if (/project_not_found/.test(topCode)) {
534
+ return {
535
+ usable: false,
536
+ blocker: 'project_not_found',
537
+ detail: `Project ID not visible to the auth'd team. Run \`vercel switch\` or verify the project ID.`,
538
+ };
539
+ }
540
+ if (/not_linked/.test(topCode)) {
541
+ return {
542
+ usable: false,
543
+ blocker: 'not_linked',
544
+ detail: `${top[1]}/${entries.length} metric queries returned NOT_LINKED. Link the app directory first: \`vercel link --yes --project <project-name-or-id> --cwd <project-dir>\`; add \`--team <team-id-or-slug>\` when the team is known.`,
545
+ };
546
+ }
547
+ return {
548
+ usable: false,
549
+ blocker: 'all_failed_other',
550
+ detail: `Every metric query failed; top error code was \`${topCode}\` (${top?.[1]}/${entries.length}).`,
551
+ };
552
+ }
553
+
554
+ // Some queries succeeded; zero rows across the board = "no traffic in window",
555
+ // NOT an Observability Plus billing issue.
556
+ const totalRows = successes.reduce((s, m) => s + (Array.isArray(m.rows) ? m.rows.length : 0), 0);
557
+ if (totalRows === 0) {
558
+ return {
559
+ usable: true,
560
+ blocker: 'no_traffic',
561
+ detail: 'Observability Plus queries succeeded but every metric returned 0 rows. Either the project has no traffic in the 14-day window, or Observability Plus retention is limited (free tier = 1 day on Pro).',
562
+ };
563
+ }
564
+
565
+ return { usable: true, blocker: null, detail: 'Observability Plus is usable; queries returned data.' };
566
+ }
567
+
568
+ // Run main() only as a CLI; the test suite imports diagnoseObservabilityPlus directly.
569
+ import { fileURLToPath } from 'node:url';
570
+ import { realpathSync } from 'node:fs';
571
+ if (process.argv[1] && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
572
+ main().catch((err) => {
573
+ console.error('[collect-signals] FAILED:', redactSensitiveText(err.message));
574
+ process.exit(1);
575
+ });
576
+ }