@astryxdesign/cli 0.7.2-canary.fdd384f → 0.7.2

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 (450) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +169 -149
  3. package/api/build/_adapter.d.mts +8 -0
  4. package/api/build/_adapter.mjs +12 -1
  5. package/api/build/build.doc.mjs +4 -0
  6. package/api/build/kit/kit.mjs +3 -11
  7. package/api/component/_adapter.d.mts +31 -0
  8. package/api/component/_adapter.mjs +119 -11
  9. package/api/component/component.doc.mjs +6 -1
  10. package/api/component/component.mjs +60 -10
  11. package/api/component/doc-links.test.mjs +386 -0
  12. package/api/discover/_adapter.d.mts +132 -12
  13. package/api/discover/_adapter.mjs +488 -27
  14. package/api/discover/_adapter.test.mjs +599 -17
  15. package/api/discover/_catalog-view.d.mts +16 -5
  16. package/api/discover/_catalog-view.mjs +32 -8
  17. package/api/discover/detail/doc/doc.mjs +9 -1
  18. package/api/discover/discover.d.mts +11 -0
  19. package/api/discover/discover.doc.mjs +9 -7
  20. package/api/discover/discover.mjs +121 -19
  21. package/api/discover/discover.type.d.mts +20 -7
  22. package/api/discover/discover.type.mjs +17 -7
  23. package/api/discover/list/list.d.mts +4 -3
  24. package/api/discover/list/list.mjs +17 -10
  25. package/api/docs/_adapter.d.mts +63 -0
  26. package/api/docs/_adapter.mjs +312 -18
  27. package/api/docs/docs.doc.mjs +2 -1
  28. package/api/docs/docs.mjs +2 -1
  29. package/api/docs/docs.test.mjs +5 -2
  30. package/api/docs/integration-tree.test.mjs +22 -0
  31. package/api/docs/list/list.mjs +12 -2
  32. package/api/docs/reference-blocks.test.mjs +1 -3
  33. package/api/doctor/_adapter.d.mts +108 -0
  34. package/api/doctor/_adapter.mjs +223 -4
  35. package/api/doctor/doctor.d.mts +199 -0
  36. package/api/doctor/doctor.doc.mjs +3 -2
  37. package/api/doctor/doctor.mjs +530 -34
  38. package/api/doctor/doctor.test.mjs +180 -14
  39. package/api/doctor/release-checks.test.mjs +156 -0
  40. package/api/doctor/theme-checks.mjs +16 -3
  41. package/api/doctor/theme-checks.test.mjs +223 -7
  42. package/api/error.d.mts +10 -0
  43. package/api/error.mjs +25 -0
  44. package/api/gap-report/gap-report.d.mts +3 -0
  45. package/api/gap-report/gap-report.doc.mjs +11 -3
  46. package/api/gap-report/gap-report.mjs +152 -48
  47. package/api/gap-report/gap-report.test.mjs +233 -0
  48. package/api/gap-report/gap-report.type.d.mts +41 -0
  49. package/api/gap-report/gap-report.type.mjs +18 -0
  50. package/api/hook/_adapter.mjs +3 -11
  51. package/api/hook/hook.doc.mjs +4 -0
  52. package/api/hook/list/list.d.mts +1 -1
  53. package/api/init/_adapter.d.mts +22 -0
  54. package/api/init/_adapter.mjs +59 -0
  55. package/api/init/init.d.mts +7 -5
  56. package/api/init/init.doc.mjs +28 -7
  57. package/api/init/init.mjs +28 -4
  58. package/api/init/init.type.d.mts +48 -3
  59. package/api/init/init.type.mjs +37 -3
  60. package/api/init/run/run.d.mts +1 -1
  61. package/api/init/run/run.mjs +15 -4
  62. package/api/init/user/user.d.mts +14 -0
  63. package/api/init/user/user.mjs +87 -0
  64. package/api/init/user/user.test.mjs +232 -0
  65. package/api/integration/_adapter.d.mts +33 -0
  66. package/api/integration/_adapter.mjs +58 -0
  67. package/api/integration/authoring-checks.mjs +100 -5
  68. package/api/integration/authoring-checks.test.mjs +769 -0
  69. package/api/integration/authoring-checks.type.d.mts +134 -0
  70. package/api/integration/authoring-checks.type.mjs +60 -1
  71. package/api/integration/integrationCheck.doc.mjs +1 -1
  72. package/api/integration/integrationComponentConflicts.doc.mjs +11 -3
  73. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  74. package/api/integration/pack-check.mjs +303 -13
  75. package/api/integration/pack-check.test.mjs +371 -10
  76. package/api/integration/validate-integration-fixes.test.mjs +67 -0
  77. package/api/integration/validate-integration.d.mts +8 -0
  78. package/api/integration/validate-integration.mjs +55 -9
  79. package/api/integration/validate-integration.test.mjs +77 -8
  80. package/api/integration/validate-integration.type.d.mts +8 -0
  81. package/api/integration/validate-integration.type.mjs +3 -1
  82. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  83. package/api/integration/validateIntegration.doc.mjs +4 -2
  84. package/api/search/_adapter.d.mts +11 -0
  85. package/api/search/_adapter.mjs +25 -0
  86. package/api/search/search.d.mts +73 -13
  87. package/api/search/search.doc.mjs +8 -3
  88. package/api/search/search.domain-priority.test.mjs +108 -18
  89. package/api/search/search.mjs +541 -52
  90. package/api/search/search.test.mjs +143 -1
  91. package/api/search/search.type.d.mts +14 -1
  92. package/api/search/search.type.mjs +6 -1
  93. package/api/swizzle/_adapter.mjs +2 -2
  94. package/api/swizzle/copy/copy.mjs +1 -1
  95. package/api/template/template-integration.test.mjs +1 -1
  96. package/api/theme/_adapter.d.mts +16 -0
  97. package/api/theme/_adapter.mjs +32 -5
  98. package/api/theme/build/build.d.mts +2 -1
  99. package/api/theme/build/build.mjs +70 -14
  100. package/api/theme/build/build.packed-old-core.test.mjs +20 -3
  101. package/api/theme/build/font-warning.mjs +5 -3
  102. package/api/theme/build/font-warning.test.mjs +2 -1
  103. package/api/theme/remove/remove.test.mjs +2 -2
  104. package/api/theme/targets/targets.mjs +3 -10
  105. package/api/theme/themeTargets.doc.mjs +4 -0
  106. package/api/theme/use/use.test.mjs +1 -1
  107. package/api/upgrade/_adapter.d.mts +40 -2
  108. package/api/upgrade/_adapter.mjs +118 -5
  109. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  110. package/api/upgrade/run/run.mjs +35 -2
  111. package/api/upgrade/status/status.d.mts +21 -5
  112. package/api/upgrade/status/status.mjs +45 -8
  113. package/api/upgrade/upgrade.doc.mjs +6 -3
  114. package/api/upgrade/upgrade.mjs +5 -1
  115. package/api/upgrade/upgrade.type.d.mts +23 -0
  116. package/api/upgrade/upgrade.type.mjs +16 -1
  117. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  118. package/assets/codemods/registry.mjs +1 -0
  119. package/assets/codemods/runner.mjs +7 -1
  120. package/assets/codemods/transforms/next/index.mjs +1 -11
  121. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  122. package/assets/discover/official-packages.json +367 -0
  123. package/assets/docs/author-a-theme.doc.mjs +2 -2
  124. package/assets/docs/browser-support.doc.mjs +1 -1
  125. package/assets/docs/getting-started.doc.mjs +23 -3
  126. package/assets/docs/styling-overview.doc.mjs +1 -1
  127. package/assets/docs/theme.doc.mjs +1 -1
  128. package/assets/docs/tree/add-a-component.doc.mjs +12 -2
  129. package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
  130. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  131. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  132. package/assets/docs/tree/block-template.doc.mjs +6 -18
  133. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  134. package/assets/docs/tree/building-blocks.doc.mjs +4 -0
  135. package/assets/docs/tree/check-the-props.doc.mjs +8 -3
  136. package/assets/docs/tree/check-your-docs.doc.mjs +30 -13
  137. package/assets/docs/tree/checks.doc.mjs +17 -17
  138. package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
  139. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  140. package/assets/docs/tree/cli.doc.mjs +6 -0
  141. package/assets/docs/tree/codemods.doc.mjs +17 -7
  142. package/assets/docs/tree/commands.doc.mjs +7 -1
  143. package/assets/docs/tree/component-family.doc.mjs +3 -5
  144. package/assets/docs/tree/component-imports.doc.mjs +13 -3
  145. package/assets/docs/tree/components.doc.mjs +7 -1
  146. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  147. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  148. package/assets/docs/tree/configuration.doc.mjs +7 -3
  149. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  150. package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
  151. package/assets/docs/tree/describe-the-component.doc.mjs +2 -2
  152. package/assets/docs/tree/docs.doc.mjs +9 -3
  153. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  154. package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
  155. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  156. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  157. package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
  158. package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
  159. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  160. package/assets/docs/tree/global.doc.mjs +131 -0
  161. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  162. package/assets/docs/tree/install-once.doc.mjs +105 -0
  163. package/assets/docs/tree/integrations.doc.mjs +13 -1
  164. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  165. package/assets/docs/tree/layout.doc.mjs +6 -6
  166. package/assets/docs/tree/links.doc.mjs +6 -5
  167. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  168. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  169. package/assets/docs/tree/migration.doc.mjs +0 -1
  170. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  171. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  172. package/assets/docs/tree/page-template.doc.mjs +3 -7
  173. package/assets/docs/tree/problems.doc.mjs +205 -0
  174. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  175. package/assets/docs/tree/publishing.doc.mjs +6 -6
  176. package/assets/docs/tree/quick-start.doc.mjs +52 -26
  177. package/assets/docs/tree/reference.doc.mjs +192 -0
  178. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  179. package/assets/docs/tree/replace-a-core-template.doc.mjs +9 -11
  180. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  181. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  182. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  183. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  184. package/assets/docs/tree/single-component.doc.mjs +14 -6
  185. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  186. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  187. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  188. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  189. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  190. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  191. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  192. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  193. package/assets/docs/tree/templates.doc.mjs +7 -1
  194. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  195. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  196. package/assets/docs/tree/themes.doc.mjs +4 -0
  197. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  198. package/assets/docs/tree/troubleshooting.doc.mjs +22 -14
  199. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  200. package/assets/docs/tree/updates.doc.mjs +92 -0
  201. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  202. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
  203. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  204. package/assets/docs/tree/versioning.doc.mjs +9 -9
  205. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  206. package/assets/docs/tree/write-the-template-file.doc.mjs +5 -5
  207. package/assets/docs/working-with-ai.doc.mjs +23 -9
  208. package/authoring/codemod/codemod.doc.mjs +7 -3
  209. package/authoring/config/config.doc.mjs +9 -6
  210. package/authoring/config/type.ts +4 -2
  211. package/authoring/debug/parse.d.mts +5 -5
  212. package/authoring/discover/discover.doc.mjs +7 -1
  213. package/authoring/doctypes/_schema.d.mts +8 -3
  214. package/authoring/doctypes/_schema.mjs +1 -0
  215. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  216. package/authoring/doctypes/command/command.doc.mjs +20 -12
  217. package/authoring/doctypes/command/type.ts +14 -0
  218. package/authoring/doctypes/component/component.doc.mjs +29 -26
  219. package/authoring/doctypes/component/type.ts +15 -5
  220. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  221. package/authoring/doctypes/function/function.doc.mjs +9 -8
  222. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  223. package/authoring/doctypes/hook/type.ts +4 -0
  224. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  225. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  226. package/authoring/doctypes/schema/schema.doc.mjs +9 -9
  227. package/authoring/doctypes/template/template.doc.mjs +2 -2
  228. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  229. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  230. package/authoring/identity/identity.doc.mjs +3 -3
  231. package/authoring/index.d.ts +1 -0
  232. package/authoring/integration/integration.doc.mjs +22 -5
  233. package/authoring/integration/parse.test.mjs +11 -0
  234. package/authoring/integration/schema.d.mts +14 -3
  235. package/authoring/integration/schema.mjs +33 -2
  236. package/authoring/integration/type.ts +8 -0
  237. package/clients/cli/bin/astryx.mjs +20 -3
  238. package/clients/cli/cli-command.test.mjs +166 -0
  239. package/clients/cli/commands/blog.doc.mjs +1 -0
  240. package/clients/cli/commands/build-theme.batch-report.test.mjs +14 -2
  241. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  242. package/clients/cli/commands/build-theme.mjs +25 -12
  243. package/clients/cli/commands/build.doc.mjs +1 -0
  244. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  245. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  246. package/clients/cli/commands/component.doc.mjs +1 -0
  247. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  248. package/clients/cli/commands/discover.doc.mjs +9 -1
  249. package/clients/cli/commands/discover.mjs +144 -93
  250. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  251. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  252. package/clients/cli/commands/docs.doc.mjs +1 -0
  253. package/clients/cli/commands/docs.mjs +49 -19
  254. package/clients/cli/commands/docs.test.mjs +2 -2
  255. package/clients/cli/commands/doctor-integration-components.doc.mjs +7 -3
  256. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  257. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  258. package/clients/cli/commands/doctor-integration-validate.doc.mjs +13 -2
  259. package/clients/cli/commands/doctor-integration.test.mjs +52 -4
  260. package/clients/cli/commands/doctor.doc.mjs +12 -2
  261. package/clients/cli/commands/doctor.mjs +102 -7
  262. package/clients/cli/commands/doctor.test.mjs +10 -4
  263. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  264. package/clients/cli/commands/gap-report.mjs +24 -2
  265. package/clients/cli/commands/gap-report.test.mjs +79 -0
  266. package/clients/cli/commands/hook.doc.mjs +1 -0
  267. package/clients/cli/commands/init.behavior.test.mjs +5 -0
  268. package/clients/cli/commands/init.doc.mjs +29 -3
  269. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  270. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  271. package/clients/cli/commands/integration-check.doc.mjs +10 -2
  272. package/clients/cli/commands/integration-check.test.mjs +175 -1
  273. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  274. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  275. package/clients/cli/commands/integration.mjs +15 -9
  276. package/clients/cli/commands/json-contract.test.mjs +11 -2
  277. package/clients/cli/commands/manifest.doc.mjs +1 -0
  278. package/clients/cli/commands/outside-project.test.mjs +774 -0
  279. package/clients/cli/commands/search.doc.mjs +1 -0
  280. package/clients/cli/commands/search.mjs +16 -11
  281. package/clients/cli/commands/search.test.mjs +429 -296
  282. package/clients/cli/commands/setup-nudge.test.mjs +102 -2
  283. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  284. package/clients/cli/commands/swizzle.mjs +5 -3
  285. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  286. package/clients/cli/commands/template.doc.mjs +1 -0
  287. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  288. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  289. package/clients/cli/commands/theme-build.doc.mjs +1 -0
  290. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  291. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  292. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  293. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  294. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  295. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  296. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  297. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  298. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  299. package/clients/cli/commands/upgrade.doc.mjs +22 -1
  300. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  301. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  302. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  303. package/clients/cli/index.mjs +111 -16
  304. package/clients/cli/lib/cli-error.mjs +4 -1
  305. package/clients/cli/lib/component-format.test.mjs +1 -1
  306. package/clients/cli/lib/define-command.mjs +2 -2
  307. package/clients/cli/lib/json-shim.mjs +3 -1
  308. package/clients/cli/lib/manifest.d.ts +9 -0
  309. package/clients/cli/lib/manifest.mjs +17 -1
  310. package/clients/cli/lib/manifest.test.mjs +25 -0
  311. package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
  312. package/foundation/agent-docs/agent-doc-state.mjs +66 -6
  313. package/foundation/agent-docs/agent-docs.d.mts +4 -3
  314. package/foundation/agent-docs/agent-docs.mjs +11 -9
  315. package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
  316. package/foundation/agent-docs/computer-agent-text.mjs +623 -0
  317. package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
  318. package/foundation/config/project.d.mts +35 -3
  319. package/foundation/config/project.mjs +145 -8
  320. package/foundation/config/project.test.mjs +66 -0
  321. package/foundation/config/theme-state.mjs +5 -4
  322. package/foundation/discovery/authoring-self-docs.mjs +1 -1
  323. package/foundation/discovery/cli-self-docs.mjs +20 -3
  324. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  325. package/foundation/discovery/component-replacement.mjs +2 -1
  326. package/foundation/discovery/copied-passages.d.mts +216 -0
  327. package/foundation/discovery/copied-passages.mjs +720 -0
  328. package/foundation/discovery/copied-passages.test.mjs +124 -0
  329. package/foundation/discovery/doc-consistency.d.mts +34 -0
  330. package/foundation/discovery/doc-consistency.mjs +513 -0
  331. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  332. package/foundation/discovery/doc-fluff.d.mts +112 -0
  333. package/foundation/discovery/doc-fluff.mjs +328 -0
  334. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  335. package/foundation/discovery/doc-types.d.mts +1 -1
  336. package/foundation/discovery/doc-types.mjs +15 -8
  337. package/foundation/discovery/doc-types.test.mjs +94 -2
  338. package/foundation/discovery/docs-discovery.d.mts +7 -0
  339. package/foundation/discovery/docs-discovery.mjs +26 -2
  340. package/foundation/discovery/project-typescript.d.mts +11 -2
  341. package/foundation/discovery/project-typescript.mjs +32 -4
  342. package/foundation/discovery/prop-drift.d.mts +26 -7
  343. package/foundation/discovery/prop-drift.mjs +173 -8
  344. package/foundation/discovery/prop-drift.test.mjs +120 -2
  345. package/foundation/discovery/runner-allowlist.d.mts +40 -0
  346. package/foundation/discovery/runner-allowlist.mjs +53 -0
  347. package/foundation/discovery/stray-pointers.d.mts +52 -0
  348. package/foundation/discovery/stray-pointers.mjs +293 -0
  349. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  350. package/foundation/discovery/template-needs.mjs +5 -2
  351. package/foundation/discovery/theme-imports.mjs +8 -4
  352. package/foundation/discovery/theme-imports.test.mjs +1 -1
  353. package/foundation/discovery/type-text.mjs +1 -1
  354. package/foundation/discovery/type-text.test.mjs +1 -1
  355. package/foundation/doc-compiler/doc-loads.test.mjs +42 -2
  356. package/foundation/doc-compiler/inputs.mjs +4 -1
  357. package/foundation/doc-compiler/links.d.mts +32 -0
  358. package/foundation/doc-compiler/links.mjs +163 -26
  359. package/foundation/doc-compiler/links.test.mjs +97 -4
  360. package/foundation/doc-compiler/read.d.mts +1 -1
  361. package/foundation/doc-compiler/tree.mjs +30 -1
  362. package/foundation/doc-compiler/tree.test.mjs +8 -1
  363. package/foundation/env/cli-command.d.mts +83 -0
  364. package/foundation/env/cli-command.mjs +152 -0
  365. package/foundation/env/cli-command.test.mjs +129 -0
  366. package/foundation/env/node-version.test.mjs +15 -3
  367. package/foundation/env/package-manager.d.mts +93 -9
  368. package/foundation/env/package-manager.global.test.mjs +66 -0
  369. package/foundation/env/package-manager.mjs +184 -13
  370. package/foundation/env/package-manager.test.mjs +341 -15
  371. package/foundation/env/project-scope.d.mts +9 -0
  372. package/foundation/env/project-scope.mjs +33 -0
  373. package/foundation/env/search-path.d.mts +42 -0
  374. package/foundation/env/search-path.mjs +205 -0
  375. package/foundation/env/search-path.test.mjs +122 -0
  376. package/foundation/env/user-dirs.d.mts +39 -0
  377. package/foundation/env/user-dirs.mjs +93 -0
  378. package/foundation/env/user-dirs.test.mjs +72 -0
  379. package/foundation/env/user-settings.d.mts +46 -0
  380. package/foundation/env/user-settings.mjs +106 -0
  381. package/foundation/env/user-settings.test.mjs +64 -0
  382. package/foundation/fs/file-protection.mjs +15 -1
  383. package/foundation/fs/module-loader.d.mts +2 -1
  384. package/foundation/fs/module-loader.mjs +60 -4
  385. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  386. package/foundation/fs/module-loader.test.mjs +194 -0
  387. package/foundation/fs/path-compare.d.mts +33 -0
  388. package/foundation/fs/path-compare.mjs +73 -0
  389. package/foundation/fs/paths.d.mts +57 -1
  390. package/foundation/fs/paths.mjs +131 -3
  391. package/foundation/fs/paths.test.mjs +10 -1
  392. package/foundation/integrations/computer-integrations.d.mts +78 -0
  393. package/foundation/integrations/computer-integrations.mjs +316 -0
  394. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  395. package/foundation/integrations/contribution-inventory.d.mts +11 -0
  396. package/foundation/integrations/contribution-inventory.mjs +50 -2
  397. package/foundation/integrations/integration-warnings.mjs +3 -2
  398. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  399. package/foundation/integrations/integrations.d.mts +25 -1
  400. package/foundation/integrations/integrations.mjs +46 -3
  401. package/foundation/integrations/issue.ts +6 -0
  402. package/foundation/integrations/validate-contributions.d.mts +2 -0
  403. package/foundation/integrations/validate-contributions.mjs +41 -1
  404. package/foundation/release/agent-text-worker.d.mts +4 -0
  405. package/foundation/release/agent-text-worker.mjs +52 -0
  406. package/foundation/release/cache.d.mts +310 -0
  407. package/foundation/release/cache.mjs +1216 -0
  408. package/foundation/release/cache.test.mjs +920 -0
  409. package/foundation/release/choose.d.mts +207 -0
  410. package/foundation/release/choose.mjs +677 -0
  411. package/foundation/release/choose.test.mjs +427 -0
  412. package/foundation/release/core-worker.d.mts +4 -0
  413. package/foundation/release/core-worker.mjs +38 -0
  414. package/foundation/release/global-state.d.mts +259 -0
  415. package/foundation/release/global-state.mjs +472 -0
  416. package/foundation/release/global-state.test.mjs +381 -0
  417. package/foundation/release/handoff.d.mts +60 -0
  418. package/foundation/release/handoff.e2e.test.mjs +278 -0
  419. package/foundation/release/handoff.mjs +357 -0
  420. package/foundation/release/lock-lease.d.mts +23 -0
  421. package/foundation/release/lock-lease.mjs +80 -0
  422. package/foundation/release/notices.d.mts +253 -0
  423. package/foundation/release/notices.mjs +596 -0
  424. package/foundation/release/notices.test.mjs +565 -0
  425. package/foundation/release/npm-guard.d.mts +4 -0
  426. package/foundation/release/npm-guard.mjs +126 -0
  427. package/foundation/release/project.d.mts +141 -0
  428. package/foundation/release/project.mjs +466 -0
  429. package/foundation/release/project.test.mjs +288 -0
  430. package/foundation/release/refresh-worker.d.mts +4 -0
  431. package/foundation/release/refresh-worker.mjs +27 -0
  432. package/foundation/release/run-context.d.mts +47 -0
  433. package/foundation/release/run-context.mjs +149 -0
  434. package/foundation/release/update-notice-env.d.mts +28 -0
  435. package/foundation/release/update-notice-env.mjs +39 -0
  436. package/foundation/response/base.d.ts +26 -3
  437. package/foundation/response/error-codes.d.mts +3 -1
  438. package/foundation/response/error-codes.doc.mjs +12 -0
  439. package/foundation/response/error-codes.mjs +17 -0
  440. package/foundation/response/error-codes.test.mjs +2 -0
  441. package/foundation/response/json-contract.test.mjs +7 -2
  442. package/foundation/response/json.mjs +4 -1
  443. package/foundation/response/response-types.doc.mjs +17 -11
  444. package/foundation/response/response-types.doc.test.mjs +46 -0
  445. package/foundation/response/response.doc.mjs +3 -3
  446. package/foundation/xle/browser-imports.test.mjs +74 -0
  447. package/package.json +11 -11
  448. package/scripts/postinstall.mjs +24 -5
  449. /package/assets/codemods/transforms/{next → v0.7.2}/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +0 -0
  450. /package/assets/codemods/transforms/{next → v0.7.2}/migrate-list-edge-compensation-to-edge.mjs +0 -0
@@ -0,0 +1,472 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The per-user update state, and the background check that keeps it
5
+ * current (spec AST-081 FR6).
6
+ *
7
+ * The CLI never installs a newer release for the computer; it tells its user
8
+ * one exists, the way `gh` and the Vercel CLI do (notices.mjs). At most once a
9
+ * day, never in the first day after the first run, a run starts a detached
10
+ * check of the release the registry tags `latest`; no run waits for it. No
11
+ * check starts when the standard `CI` variable is set, or when
12
+ * `NO_UPDATE_NOTIFIER` is (update-notice-env.mjs).
13
+ *
14
+ * <user config>/astryx/state.json
15
+ * firstRunAt when a run first kept this state (no check before a day)
16
+ * checkedAt when the last check started
17
+ * checkOkAt when a check last reached the registry
18
+ * latest the version `latest` named then
19
+ * latestNode the Node range that release declares, or null
20
+ * agentText the computer-level agent text: {writtenBy, attemptFor,
21
+ * attemptAt}, the release that last wrote it and the last
22
+ * background attempt (spec AST-081 FR8)
23
+ * notifiedAt when each update notice last printed (notices.mjs)
24
+ *
25
+ * @input the clock, the registry's `latest` tag (in the worker)
26
+ * @output the newest release known, for notices and doctor
27
+ * @position foundation/release — read by the bin and doctor; the check runs
28
+ * in refresh-worker.mjs.
29
+ */
30
+
31
+ import * as fs from 'node:fs';
32
+ import * as path from 'node:path';
33
+ import {spawn} from 'node:child_process';
34
+ import {fileURLToPath} from 'node:url';
35
+ import {
36
+ cachedRelease,
37
+ isReleaseVersion,
38
+ recentFailedInstall,
39
+ releasesDir,
40
+ resolveLatestRelease,
41
+ tryLock,
42
+ } from './cache.mjs';
43
+ import {readJson} from './project.mjs';
44
+ import {userConfigDir} from '../env/user-dirs.mjs';
45
+ import {computerAgentTextSettings} from '../env/user-settings.mjs';
46
+ import {isCi, updateNoticesOff} from './update-notice-env.mjs';
47
+
48
+ /** How often a check may start: once a day, as `gh` and update-notifier do. */
49
+ export const CHECK_INTERVAL_MS = 24 * 60 * 60_000;
50
+
51
+ /**
52
+ * @typedef {object} GlobalState
53
+ * @property {number} [firstRunAt]
54
+ * @property {number} [checkedAt]
55
+ * @property {number} [checkOkAt]
56
+ * @property {string} [latest]
57
+ * @property {string | null} [latestNode]
58
+ * @property {{at: number, reason: string}} [checkFailed] why the last check
59
+ * did not reach the registry, for diagnosis only (`astryx doctor`); cleared
60
+ * by a check that does. Not part of any contract.
61
+ * @property {{writtenBy?: string, attemptFor?: string, attemptAt?: number}} [agentText]
62
+ * @property {Record<string, number>} [notifiedAt] when each update notice
63
+ * last printed (notices.mjs)
64
+ * @property {Record<string, NoticeSkip>} [noticeSkips] why each update notice
65
+ * last did not print, for diagnosis only: `astryx doctor` shows the newest.
66
+ * Not part of any contract; its shape may change in any release.
67
+ */
68
+
69
+ /**
70
+ * Why an update notice did not print: `already-shown` (it printed within the
71
+ * day) or `no-newer` (nothing newer is known). Recorded only while the run
72
+ * holds the state file's lock.
73
+ * @typedef {{reason: 'already-shown' | 'no-newer', at: number}} NoticeSkip
74
+ */
75
+
76
+ /**
77
+ * The state file.
78
+ * @param {string} [stateDir] the per-user configuration folder
79
+ * @returns {string}
80
+ */
81
+ export function stateFile(stateDir = userConfigDir()) {
82
+ return path.join(stateDir, 'state.json');
83
+ }
84
+
85
+ /**
86
+ * The saved state; `{}` when there is none or it cannot be read.
87
+ * @param {string} [stateDir]
88
+ * @returns {GlobalState}
89
+ */
90
+ export function readGlobalState(stateDir = userConfigDir()) {
91
+ const state = readJson(stateFile(stateDir));
92
+ return state && typeof state === 'object' && !Array.isArray(state)
93
+ ? state
94
+ : {};
95
+ }
96
+
97
+ /** How long a run waits for another run's change to the state file. */
98
+ const STATE_LOCK_WAIT_MS = 2000;
99
+
100
+ /** Sleep the thread without spinning. @param {number} ms */
101
+ function sleep(ms) {
102
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
103
+ }
104
+
105
+ /**
106
+ * Run `change` while holding the state file's lock, so runs that finish at
107
+ * the same moment change the state one at a time: each reads what the one
108
+ * before it wrote. Returns `change`'s result, or `undefined` when the lock
109
+ * cannot be taken in time or the folder cannot be written, in which case
110
+ * nothing changes.
111
+ * @template T
112
+ * @param {string} stateDir
113
+ * @param {() => T} change
114
+ * @returns {T | undefined}
115
+ */
116
+ export function withStateLock(stateDir, change) {
117
+ const outcome = tryStateLock(stateDir, change);
118
+ return outcome.ran ? outcome.value : undefined;
119
+ }
120
+
121
+ /**
122
+ * Who holds the state file's lock now, read from its owner record, for
123
+ * diagnosis: null when it is free. `since` is when the lock folder was made.
124
+ * @param {string} [stateDir]
125
+ * @returns {{pid: number | null, host: string | null, since: number} | null}
126
+ */
127
+ export function stateLockHolder(stateDir = userConfigDir()) {
128
+ const lockDir = path.join(stateDir, '.lock-state');
129
+ try {
130
+ const since = fs.statSync(lockDir).mtimeMs;
131
+ const owner = readJson(path.join(lockDir, 'owner.json'));
132
+ return {
133
+ pid: Number.isInteger(owner?.pid) ? owner.pid : null,
134
+ host: typeof owner?.host === 'string' ? owner.host : null,
135
+ since,
136
+ };
137
+ } catch {
138
+ return null;
139
+ }
140
+ }
141
+
142
+ /**
143
+ * {@link withStateLock}, saying why `change` did not run: the lock stayed
144
+ * taken past the wait (`lock-timeout`), or the folder cannot hold it
145
+ * (`state-unwritable`).
146
+ * @template T
147
+ * @param {string} stateDir
148
+ * @param {() => T} change
149
+ * @returns {{ran: true, value: T} | {ran: false, reason: 'lock-timeout' | 'state-unwritable'}}
150
+ */
151
+ export function tryStateLock(stateDir, change) {
152
+ const lockDir = path.join(stateDir, '.lock-state');
153
+ const deadline = Date.now() + STATE_LOCK_WAIT_MS;
154
+ try {
155
+ while (!tryLock(lockDir)) {
156
+ if (Date.now() > deadline) return {ran: false, reason: 'lock-timeout'};
157
+ sleep(10);
158
+ }
159
+ } catch {
160
+ return {ran: false, reason: 'state-unwritable'};
161
+ }
162
+ try {
163
+ return {ran: true, value: change()};
164
+ } finally {
165
+ fs.rmSync(lockDir, {recursive: true, force: true});
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Write the whole state, atomically. Call only while holding the lock.
171
+ * @param {GlobalState} state
172
+ * @param {string} stateDir
173
+ * @returns {boolean} whether it was written
174
+ */
175
+ export function writeGlobalState(state, stateDir) {
176
+ const file = stateFile(stateDir);
177
+ try {
178
+ const tmp = `${file}.${process.pid}.tmp`;
179
+ fs.writeFileSync(tmp, `${JSON.stringify(state, null, 2)}\n`);
180
+ fs.renameSync(tmp, file);
181
+ return true;
182
+ } catch {
183
+ return false;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Merge `patch` into the saved state under the lock. An unwritable folder
189
+ * never fails a run; the state is simply not kept.
190
+ * @param {Partial<GlobalState>} patch
191
+ * @param {string} [stateDir]
192
+ * @returns {GlobalState}
193
+ */
194
+ export function updateGlobalState(patch, stateDir = userConfigDir()) {
195
+ try {
196
+ fs.mkdirSync(stateDir, {recursive: true});
197
+ } catch {
198
+ // Unwritable: nothing is kept.
199
+ }
200
+ return (
201
+ withStateLock(stateDir, () => {
202
+ const next = {...readGlobalState(stateDir), ...patch};
203
+ writeGlobalState(next, stateDir);
204
+ return next;
205
+ }) ?? {...readGlobalState(stateDir), ...patch}
206
+ );
207
+ }
208
+
209
+ /**
210
+ * The newest release the last check found, and the Node range it declares;
211
+ * null when no check has reached the registry.
212
+ * @param {string} [stateDir]
213
+ * @returns {{version: string, node: string | null} | null}
214
+ */
215
+ export function knownLatest(stateDir = userConfigDir()) {
216
+ const state = readGlobalState(stateDir);
217
+ if (typeof state.checkOkAt !== 'number' || !isReleaseVersion(state.latest)) {
218
+ return null;
219
+ }
220
+ return {
221
+ version: state.latest,
222
+ node: typeof state.latestNode === 'string' ? state.latestNode : null,
223
+ };
224
+ }
225
+
226
+ /**
227
+ * The version of the newest release known, or null.
228
+ * @param {string} [stateDir]
229
+ * @returns {string | null}
230
+ */
231
+ export function knownLatestRelease(stateDir = userConfigDir()) {
232
+ return knownLatest(stateDir)?.version ?? null;
233
+ }
234
+
235
+ /**
236
+ * Record the release that last wrote the computer-level agent text.
237
+ * @param {string | null} version
238
+ * @param {string} [stateDir]
239
+ */
240
+ export function recordAgentTextWritten(version, stateDir = userConfigDir()) {
241
+ if (!isReleaseVersion(version)) return;
242
+ updateGlobalState({agentText: {writtenBy: version}}, stateDir);
243
+ }
244
+
245
+ /** A background attempt to write the agent text is retried after an hour. */
246
+ export const AGENT_TEXT_RETRY_MS = 60 * 60_000;
247
+
248
+ /**
249
+ * The global copy keeps the computer-level agent text installed (spec
250
+ * AST-081 FR8): when the person has not turned it off and the running global
251
+ * version has not written it yet, as after the person upgraded the global
252
+ * copy, that release's own background step writes it, detached, so no command
253
+ * waits. Returns whether a step was started.
254
+ *
255
+ * @param {{
256
+ * release: {version: string, root: string},
257
+ * stateDir?: string,
258
+ * configDir?: string,
259
+ * now?: number,
260
+ * start?: (worker: string, stateDir: string) => void,
261
+ * }} options
262
+ * @returns {boolean}
263
+ */
264
+ export function maybeKeepAgentText({
265
+ release,
266
+ stateDir = userConfigDir(),
267
+ configDir,
268
+ now = Date.now(),
269
+ start = startWorker,
270
+ }) {
271
+ if (!computerAgentTextSettings(configDir).install) return false;
272
+ const {agentText} = readGlobalState(stateDir);
273
+ if (agentText?.writtenBy === release.version) return false;
274
+ if (
275
+ agentText?.attemptFor === release.version &&
276
+ typeof agentText.attemptAt === 'number' &&
277
+ now - agentText.attemptAt < AGENT_TEXT_RETRY_MS
278
+ ) {
279
+ return false;
280
+ }
281
+ const worker = path.join(
282
+ release.root,
283
+ 'foundation',
284
+ 'release',
285
+ 'agent-text-worker.mjs',
286
+ );
287
+ // A release without the step predates it; it never writes the text.
288
+ if (!fs.existsSync(worker)) return false;
289
+ updateGlobalState(
290
+ {agentText: {...agentText, attemptFor: release.version, attemptAt: now}},
291
+ stateDir,
292
+ );
293
+ // An attempt that cannot be recorded would start again on every run.
294
+ if (readGlobalState(stateDir).agentText?.attemptAt !== now) return false;
295
+ start(worker, stateDir);
296
+ return true;
297
+ }
298
+
299
+ /**
300
+ * Start the background step that installs this release's Core into the
301
+ * per-user cache, so commands that read Core work offline outside a project
302
+ * after one online run (spec AST-081 FR3, FR6): when the global copy carries
303
+ * no Core beside it and none is cached for its release, no install of it is
304
+ * under way, no recent attempt failed (the release cache's backoff), and
305
+ * `CI` is not set. It never blocks a command, prints nothing, and a failure
306
+ * is retried by a later run's step. Returns whether it was started.
307
+ *
308
+ * Never on Windows: a detached child there inherits the caller's open handles,
309
+ * such as the pipes a tool or agent reads this run's output from, and the
310
+ * caller would wait for the download to end. A component read on Windows
311
+ * fetches the Core itself when it first needs it.
312
+ * @param {{release: {version: string, root: string}, cacheDir: string, env?: NodeJS.ProcessEnv, start?: typeof startWorker, platform?: NodeJS.Platform}} options
313
+ * @returns {boolean}
314
+ */
315
+ export function maybeFetchCore({
316
+ release,
317
+ cacheDir,
318
+ env = process.env,
319
+ start = startWorker,
320
+ platform = process.platform,
321
+ }) {
322
+ if (isCi(env) || platform === 'win32') return false;
323
+ if (!isReleaseVersion(release.version)) return false;
324
+ const beside = readJson(
325
+ path.join(release.root, '..', 'core', 'package.json'),
326
+ );
327
+ if (
328
+ beside?.name === '@astryxdesign/core' &&
329
+ beside.version === release.version
330
+ ) {
331
+ return false;
332
+ }
333
+ if (cachedRelease(release.version, cacheDir)) return false;
334
+ if (recentFailedInstall(release.version, cacheDir)) return false;
335
+ if (
336
+ fs.existsSync(path.join(releasesDir(cacheDir), `.lock-${release.version}`))
337
+ ) {
338
+ return false;
339
+ }
340
+ const worker = path.join(
341
+ release.root,
342
+ 'foundation',
343
+ 'release',
344
+ 'core-worker.mjs',
345
+ );
346
+ // A release without the step predates it.
347
+ if (!fs.existsSync(worker)) return false;
348
+ start(worker, cacheDir);
349
+ return true;
350
+ }
351
+
352
+ /**
353
+ * Start the background check when one is due: never when the environment
354
+ * turns update notices off (`CI`, `NO_UPDATE_NOTIFIER`), never in the first
355
+ * day after the first run, and at most once a day. Returns whether a check
356
+ * was started.
357
+ *
358
+ * @param {{
359
+ * stateDir?: string,
360
+ * now?: number,
361
+ * env?: Record<string, string | undefined>,
362
+ * start?: (worker: string, stateDir: string) => void,
363
+ * }} [options]
364
+ * @returns {boolean}
365
+ */
366
+ export function maybeStartCheck(options = {}) {
367
+ const {
368
+ stateDir = userConfigDir(),
369
+ now = Date.now(),
370
+ env = process.env,
371
+ start = startWorker,
372
+ } = options;
373
+ if (updateNoticesOff(env)) return false;
374
+ const state = readGlobalState(stateDir);
375
+ if (typeof state.firstRunAt !== 'number') {
376
+ updateGlobalState({firstRunAt: now}, stateDir);
377
+ return false;
378
+ }
379
+ const last = Math.max(state.firstRunAt, state.checkedAt ?? 0);
380
+ if (now - last < CHECK_INTERVAL_MS) return false;
381
+ updateGlobalState({checkedAt: now}, stateDir);
382
+ // A start time that cannot be recorded would start a check on every run.
383
+ if (readGlobalState(stateDir).checkedAt !== now) return false;
384
+ start(
385
+ fileURLToPath(new URL('./refresh-worker.mjs', import.meta.url)),
386
+ stateDir,
387
+ );
388
+ return true;
389
+ }
390
+
391
+ /**
392
+ * Why the last update check did not reach the registry, when it failed after
393
+ * the last one that did; null otherwise. For diagnosis only.
394
+ * @param {string} [stateDir]
395
+ * @returns {{at: number, reason: string} | null}
396
+ */
397
+ export function lastCheckFailure(stateDir = userConfigDir()) {
398
+ const state = readGlobalState(stateDir);
399
+ const failed = state.checkFailed;
400
+ if (
401
+ !failed ||
402
+ typeof failed.at !== 'number' ||
403
+ typeof failed.reason !== 'string'
404
+ ) {
405
+ return null;
406
+ }
407
+ return typeof state.checkOkAt === 'number' && state.checkOkAt > failed.at
408
+ ? null
409
+ : {at: failed.at, reason: failed.reason};
410
+ }
411
+
412
+ /**
413
+ * Start a detached worker that outlives this run and reaches no stream.
414
+ * @param {string} worker
415
+ * @param {string} stateDir
416
+ */
417
+ function startWorker(worker, stateDir) {
418
+ try {
419
+ const child = spawn(process.execPath, [worker, stateDir], {
420
+ detached: true,
421
+ stdio: 'ignore',
422
+ windowsHide: true,
423
+ });
424
+ child.on('error', () => {});
425
+ child.unref();
426
+ } catch {
427
+ // A check that cannot start is the same as a failed check.
428
+ }
429
+ }
430
+
431
+ /**
432
+ * The check itself: ask the registry for `latest` and save what it says. It
433
+ * installs nothing. At most one check runs at a time.
434
+ * @param {{stateDir?: string, resolve?: typeof resolveLatestRelease}} [options]
435
+ * @returns {GlobalState}
436
+ */
437
+ export function runCheck(options = {}) {
438
+ const {stateDir = userConfigDir(), resolve = resolveLatestRelease} = options;
439
+ const lockDir = path.join(stateDir, '.lock-check');
440
+ try {
441
+ if (!tryLock(lockDir)) return readGlobalState(stateDir);
442
+ } catch {
443
+ return readGlobalState(stateDir);
444
+ }
445
+ try {
446
+ /** @type {string} */
447
+ let reason = 'unknown';
448
+ const latest = resolve({
449
+ onFailure: why => {
450
+ reason = why;
451
+ },
452
+ });
453
+ if (!latest) {
454
+ // Recorded so doctor can say why notices stopped (diagnosis only).
455
+ return updateGlobalState(
456
+ {checkFailed: {at: Date.now(), reason}},
457
+ stateDir,
458
+ );
459
+ }
460
+ return updateGlobalState(
461
+ {
462
+ latest: latest.version,
463
+ latestNode: latest.node,
464
+ checkOkAt: Date.now(),
465
+ checkFailed: undefined,
466
+ },
467
+ stateDir,
468
+ );
469
+ } finally {
470
+ fs.rmSync(lockDir, {recursive: true, force: true});
471
+ }
472
+ }