@cbnventures/nova 0.17.0 → 0.18.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 (643) hide show
  1. package/LICENSE +22 -0
  2. package/build/package.json +1 -1
  3. package/build/src/api/node-releases.d.ts +4 -4
  4. package/build/src/api/node-releases.d.ts.map +1 -1
  5. package/build/src/api/node-releases.js +14 -14
  6. package/build/src/api/node-releases.js.map +1 -1
  7. package/build/src/api/spdx-licenses.d.ts +4 -4
  8. package/build/src/api/spdx-licenses.d.ts.map +1 -1
  9. package/build/src/api/spdx-licenses.js +12 -12
  10. package/build/src/api/spdx-licenses.js.map +1 -1
  11. package/build/src/cli/generate/github/funding.d.ts +3 -3
  12. package/build/src/cli/generate/github/funding.d.ts.map +1 -1
  13. package/build/src/cli/generate/github/funding.js +5 -5
  14. package/build/src/cli/generate/github/funding.js.map +1 -1
  15. package/build/src/cli/generate/github/issue-template.d.ts +3 -3
  16. package/build/src/cli/generate/github/issue-template.d.ts.map +1 -1
  17. package/build/src/cli/generate/github/issue-template.js +14 -12
  18. package/build/src/cli/generate/github/issue-template.js.map +1 -1
  19. package/build/src/cli/generate/github/workflows.d.ts +10 -10
  20. package/build/src/cli/generate/github/workflows.d.ts.map +1 -1
  21. package/build/src/cli/generate/github/workflows.js +222 -104
  22. package/build/src/cli/generate/github/workflows.js.map +1 -1
  23. package/build/src/cli/generate/must-haves/agent-conventions.d.ts +3 -3
  24. package/build/src/cli/generate/must-haves/agent-conventions.d.ts.map +1 -1
  25. package/build/src/cli/generate/must-haves/agent-conventions.js +11 -11
  26. package/build/src/cli/generate/must-haves/agent-conventions.js.map +1 -1
  27. package/build/src/cli/generate/must-haves/dotenv.d.ts +3 -3
  28. package/build/src/cli/generate/must-haves/dotenv.d.ts.map +1 -1
  29. package/build/src/cli/generate/must-haves/dotenv.js +69 -69
  30. package/build/src/cli/generate/must-haves/dotenv.js.map +1 -1
  31. package/build/src/cli/generate/must-haves/editorconfig.d.ts +3 -3
  32. package/build/src/cli/generate/must-haves/editorconfig.d.ts.map +1 -1
  33. package/build/src/cli/generate/must-haves/editorconfig.js +3 -3
  34. package/build/src/cli/generate/must-haves/editorconfig.js.map +1 -1
  35. package/build/src/cli/generate/must-haves/gitignore.d.ts +3 -3
  36. package/build/src/cli/generate/must-haves/gitignore.d.ts.map +1 -1
  37. package/build/src/cli/generate/must-haves/gitignore.js +69 -67
  38. package/build/src/cli/generate/must-haves/gitignore.js.map +1 -1
  39. package/build/src/cli/generate/must-haves/license.d.ts +3 -3
  40. package/build/src/cli/generate/must-haves/license.d.ts.map +1 -1
  41. package/build/src/cli/generate/must-haves/license.js +11 -7
  42. package/build/src/cli/generate/must-haves/license.js.map +1 -1
  43. package/build/src/cli/generate/must-haves/read-me.d.ts +3 -3
  44. package/build/src/cli/generate/must-haves/read-me.d.ts.map +1 -1
  45. package/build/src/cli/generate/must-haves/read-me.js +20 -27
  46. package/build/src/cli/generate/must-haves/read-me.js.map +1 -1
  47. package/build/src/cli/index.js +81 -34
  48. package/build/src/cli/index.js.map +1 -1
  49. package/build/src/cli/recipe/github/handle-gh-failure.d.ts +3 -0
  50. package/build/src/cli/recipe/github/handle-gh-failure.d.ts.map +1 -0
  51. package/build/src/cli/recipe/github/handle-gh-failure.js +22 -0
  52. package/build/src/cli/recipe/github/handle-gh-failure.js.map +1 -0
  53. package/build/src/cli/recipe/github/sync-features.d.ts +5 -0
  54. package/build/src/cli/recipe/github/sync-features.d.ts.map +1 -0
  55. package/build/src/cli/recipe/github/sync-features.js +145 -0
  56. package/build/src/cli/recipe/github/sync-features.js.map +1 -0
  57. package/build/src/cli/recipe/github/sync-identity.d.ts +6 -0
  58. package/build/src/cli/recipe/github/sync-identity.d.ts.map +1 -0
  59. package/build/src/cli/recipe/github/sync-identity.js +191 -0
  60. package/build/src/cli/recipe/github/sync-identity.js.map +1 -0
  61. package/build/src/cli/recipe/github/sync-policies.d.ts +5 -0
  62. package/build/src/cli/recipe/github/sync-policies.d.ts.map +1 -0
  63. package/build/src/cli/recipe/github/sync-policies.js +154 -0
  64. package/build/src/cli/recipe/github/sync-policies.js.map +1 -0
  65. package/build/src/cli/recipe/index.d.ts +2 -2
  66. package/build/src/cli/recipe/index.d.ts.map +1 -1
  67. package/build/src/cli/recipe/index.js +66 -56
  68. package/build/src/cli/recipe/index.js.map +1 -1
  69. package/build/src/cli/recipe/package-json/cleanup.d.ts +3 -3
  70. package/build/src/cli/recipe/package-json/cleanup.d.ts.map +1 -1
  71. package/build/src/cli/recipe/package-json/cleanup.js +25 -24
  72. package/build/src/cli/recipe/package-json/cleanup.js.map +1 -1
  73. package/build/src/cli/recipe/package-json/normalize-artifacts.d.ts +3 -3
  74. package/build/src/cli/recipe/package-json/normalize-artifacts.d.ts.map +1 -1
  75. package/build/src/cli/recipe/package-json/normalize-artifacts.js +35 -35
  76. package/build/src/cli/recipe/package-json/normalize-artifacts.js.map +1 -1
  77. package/build/src/cli/recipe/package-json/normalize-bundler.d.ts +3 -3
  78. package/build/src/cli/recipe/package-json/normalize-bundler.d.ts.map +1 -1
  79. package/build/src/cli/recipe/package-json/normalize-bundler.js +22 -22
  80. package/build/src/cli/recipe/package-json/normalize-bundler.js.map +1 -1
  81. package/build/src/cli/recipe/package-json/normalize-dependencies.d.ts +3 -3
  82. package/build/src/cli/recipe/package-json/normalize-dependencies.d.ts.map +1 -1
  83. package/build/src/cli/recipe/package-json/normalize-dependencies.js +37 -37
  84. package/build/src/cli/recipe/package-json/normalize-dependencies.js.map +1 -1
  85. package/build/src/cli/recipe/package-json/normalize-modules.d.ts +3 -3
  86. package/build/src/cli/recipe/package-json/normalize-modules.d.ts.map +1 -1
  87. package/build/src/cli/recipe/package-json/normalize-modules.js +47 -47
  88. package/build/src/cli/recipe/package-json/normalize-modules.js.map +1 -1
  89. package/build/src/cli/recipe/package-json/normalize-tooling.d.ts +3 -3
  90. package/build/src/cli/recipe/package-json/normalize-tooling.d.ts.map +1 -1
  91. package/build/src/cli/recipe/package-json/normalize-tooling.js +23 -23
  92. package/build/src/cli/recipe/package-json/normalize-tooling.js.map +1 -1
  93. package/build/src/cli/recipe/package-json/sync-environment.d.ts +3 -3
  94. package/build/src/cli/recipe/package-json/sync-environment.d.ts.map +1 -1
  95. package/build/src/cli/recipe/package-json/sync-environment.js +37 -37
  96. package/build/src/cli/recipe/package-json/sync-environment.js.map +1 -1
  97. package/build/src/cli/recipe/package-json/sync-identity.d.ts +3 -3
  98. package/build/src/cli/recipe/package-json/sync-identity.d.ts.map +1 -1
  99. package/build/src/cli/recipe/package-json/sync-identity.js +20 -20
  100. package/build/src/cli/recipe/package-json/sync-identity.js.map +1 -1
  101. package/build/src/cli/recipe/package-json/sync-ownership.d.ts +3 -3
  102. package/build/src/cli/recipe/package-json/sync-ownership.d.ts.map +1 -1
  103. package/build/src/cli/recipe/package-json/sync-ownership.js +28 -28
  104. package/build/src/cli/recipe/package-json/sync-ownership.js.map +1 -1
  105. package/build/src/cli/scaffold/app/expressjs.d.ts +3 -3
  106. package/build/src/cli/scaffold/app/expressjs.d.ts.map +1 -1
  107. package/build/src/cli/scaffold/app/expressjs.js +1 -1
  108. package/build/src/cli/scaffold/app/expressjs.js.map +1 -1
  109. package/build/src/cli/scaffold/app/nextjs.d.ts +3 -3
  110. package/build/src/cli/scaffold/app/nextjs.d.ts.map +1 -1
  111. package/build/src/cli/scaffold/app/nextjs.js +1 -1
  112. package/build/src/cli/scaffold/app/nextjs.js.map +1 -1
  113. package/build/src/cli/scaffold/app/vite.d.ts +3 -3
  114. package/build/src/cli/scaffold/app/vite.d.ts.map +1 -1
  115. package/build/src/cli/scaffold/app/vite.js +1 -1
  116. package/build/src/cli/scaffold/app/vite.js.map +1 -1
  117. package/build/src/cli/scaffold/app/workers.d.ts +3 -3
  118. package/build/src/cli/scaffold/app/workers.d.ts.map +1 -1
  119. package/build/src/cli/scaffold/app/workers.js +1 -1
  120. package/build/src/cli/scaffold/app/workers.js.map +1 -1
  121. package/build/src/cli/scaffold/docs/docusaurus.d.ts +3 -3
  122. package/build/src/cli/scaffold/docs/docusaurus.d.ts.map +1 -1
  123. package/build/src/cli/scaffold/docs/docusaurus.js +1 -1
  124. package/build/src/cli/scaffold/docs/docusaurus.js.map +1 -1
  125. package/build/src/cli/scaffold/starter/base.d.ts +3 -3
  126. package/build/src/cli/scaffold/starter/base.d.ts.map +1 -1
  127. package/build/src/cli/scaffold/starter/base.js +7 -7
  128. package/build/src/cli/scaffold/starter/base.js.map +1 -1
  129. package/build/src/cli/utility/changelog.d.ts +4 -3
  130. package/build/src/cli/utility/changelog.d.ts.map +1 -1
  131. package/build/src/cli/utility/changelog.js +84 -83
  132. package/build/src/cli/utility/changelog.js.map +1 -1
  133. package/build/src/cli/utility/initialize.d.ts +5 -3
  134. package/build/src/cli/utility/initialize.d.ts.map +1 -1
  135. package/build/src/cli/utility/initialize.js +805 -244
  136. package/build/src/cli/utility/initialize.js.map +1 -1
  137. package/build/src/cli/utility/run-recipes.d.ts +3 -3
  138. package/build/src/cli/utility/run-recipes.d.ts.map +1 -1
  139. package/build/src/cli/utility/run-recipes.js +43 -12
  140. package/build/src/cli/utility/run-recipes.js.map +1 -1
  141. package/build/src/cli/utility/run-scripts.d.ts +3 -3
  142. package/build/src/cli/utility/run-scripts.d.ts.map +1 -1
  143. package/build/src/cli/utility/run-scripts.js +9 -8
  144. package/build/src/cli/utility/run-scripts.js.map +1 -1
  145. package/build/src/cli/utility/transpile.d.ts +3 -3
  146. package/build/src/cli/utility/transpile.d.ts.map +1 -1
  147. package/build/src/cli/utility/transpile.js +4 -4
  148. package/build/src/cli/utility/transpile.js.map +1 -1
  149. package/build/src/cli/utility/type-check.d.ts +3 -3
  150. package/build/src/cli/utility/type-check.d.ts.map +1 -1
  151. package/build/src/cli/utility/type-check.js +4 -4
  152. package/build/src/cli/utility/type-check.js.map +1 -1
  153. package/build/src/cli/utility/version.d.ts +3 -3
  154. package/build/src/cli/utility/version.d.ts.map +1 -1
  155. package/build/src/cli/utility/version.js +102 -102
  156. package/build/src/cli/utility/version.js.map +1 -1
  157. package/build/src/lib/constants.d.ts +3 -2
  158. package/build/src/lib/constants.d.ts.map +1 -1
  159. package/build/src/lib/constants.js +1 -0
  160. package/build/src/lib/constants.js.map +1 -1
  161. package/build/src/lib/item.d.ts +32 -31
  162. package/build/src/lib/item.d.ts.map +1 -1
  163. package/build/src/lib/item.js +3 -1
  164. package/build/src/lib/item.js.map +1 -1
  165. package/build/src/lib/nova-config.d.ts +11 -5
  166. package/build/src/lib/nova-config.d.ts.map +1 -1
  167. package/build/src/lib/nova-config.js +143 -8
  168. package/build/src/lib/nova-config.js.map +1 -1
  169. package/build/src/lib/regex.d.ts +15 -1
  170. package/build/src/lib/regex.d.ts.map +1 -1
  171. package/build/src/lib/regex.js +15 -1
  172. package/build/src/lib/regex.js.map +1 -1
  173. package/build/src/lib/scaffold.d.ts +9 -9
  174. package/build/src/lib/scaffold.d.ts.map +1 -1
  175. package/build/src/lib/scaffold.js +45 -44
  176. package/build/src/lib/scaffold.js.map +1 -1
  177. package/build/src/lib/utility.d.ts +26 -22
  178. package/build/src/lib/utility.d.ts.map +1 -1
  179. package/build/src/lib/utility.js +83 -17
  180. package/build/src/lib/utility.js.map +1 -1
  181. package/build/src/lib/workflow-templates.d.ts +2 -2
  182. package/build/src/lib/workflow-templates.d.ts.map +1 -1
  183. package/build/src/lib/workflow-templates.js +42 -0
  184. package/build/src/lib/workflow-templates.js.map +1 -1
  185. package/build/src/presets/eslint/dx-code-style.d.ts +2 -2
  186. package/build/src/presets/eslint/dx-code-style.d.ts.map +1 -1
  187. package/build/src/presets/eslint/dx-code-style.js.map +1 -1
  188. package/build/src/presets/eslint/dx-ignore.d.ts +2 -2
  189. package/build/src/presets/eslint/dx-ignore.d.ts.map +1 -1
  190. package/build/src/presets/eslint/dx-ignore.js.map +1 -1
  191. package/build/src/presets/eslint/fw-docusaurus.d.ts +2 -2
  192. package/build/src/presets/eslint/fw-docusaurus.d.ts.map +1 -1
  193. package/build/src/presets/eslint/fw-docusaurus.js.map +1 -1
  194. package/build/src/presets/eslint/fw-expressjs.d.ts +2 -2
  195. package/build/src/presets/eslint/fw-expressjs.d.ts.map +1 -1
  196. package/build/src/presets/eslint/fw-expressjs.js.map +1 -1
  197. package/build/src/presets/eslint/fw-nextjs.d.ts +2 -2
  198. package/build/src/presets/eslint/fw-nextjs.d.ts.map +1 -1
  199. package/build/src/presets/eslint/fw-nextjs.js.map +1 -1
  200. package/build/src/presets/eslint/lang-javascript.d.ts +2 -2
  201. package/build/src/presets/eslint/lang-javascript.d.ts.map +1 -1
  202. package/build/src/presets/eslint/lang-javascript.js.map +1 -1
  203. package/build/src/presets/eslint/lang-mdx.d.ts +2 -2
  204. package/build/src/presets/eslint/lang-mdx.d.ts.map +1 -1
  205. package/build/src/presets/eslint/lang-mdx.js.map +1 -1
  206. package/build/src/presets/eslint/lang-typescript.d.ts +2 -2
  207. package/build/src/presets/eslint/lang-typescript.d.ts.map +1 -1
  208. package/build/src/presets/eslint/lang-typescript.js.map +1 -1
  209. package/build/src/presets/eslint/runtime-browser.d.ts +2 -2
  210. package/build/src/presets/eslint/runtime-browser.d.ts.map +1 -1
  211. package/build/src/presets/eslint/runtime-browser.js.map +1 -1
  212. package/build/src/presets/eslint/runtime-cloudflare-workers.d.ts +2 -2
  213. package/build/src/presets/eslint/runtime-cloudflare-workers.d.ts.map +1 -1
  214. package/build/src/presets/eslint/runtime-cloudflare-workers.js.map +1 -1
  215. package/build/src/presets/eslint/runtime-edge.d.ts +2 -2
  216. package/build/src/presets/eslint/runtime-edge.d.ts.map +1 -1
  217. package/build/src/presets/eslint/runtime-edge.js.map +1 -1
  218. package/build/src/presets/eslint/runtime-node.d.ts +2 -2
  219. package/build/src/presets/eslint/runtime-node.d.ts.map +1 -1
  220. package/build/src/presets/eslint/runtime-node.js.map +1 -1
  221. package/build/src/presets/eslint/runtime-service-worker.d.ts +2 -2
  222. package/build/src/presets/eslint/runtime-service-worker.d.ts.map +1 -1
  223. package/build/src/presets/eslint/runtime-service-worker.js.map +1 -1
  224. package/build/src/presets/eslint/runtime-web-worker.d.ts +2 -2
  225. package/build/src/presets/eslint/runtime-web-worker.d.ts.map +1 -1
  226. package/build/src/presets/eslint/runtime-web-worker.js.map +1 -1
  227. package/build/src/presets/eslint/tool-vite.d.ts +2 -2
  228. package/build/src/presets/eslint/tool-vite.d.ts.map +1 -1
  229. package/build/src/presets/eslint/tool-vite.js.map +1 -1
  230. package/build/src/rules/eslint/conventions/no-default-export-declaration.d.ts +3 -3
  231. package/build/src/rules/eslint/conventions/no-default-export-declaration.d.ts.map +1 -1
  232. package/build/src/rules/eslint/conventions/no-default-export-declaration.js +2 -2
  233. package/build/src/rules/eslint/conventions/no-default-export-declaration.js.map +1 -1
  234. package/build/src/rules/eslint/conventions/no-implicit-boolean.d.ts +3 -3
  235. package/build/src/rules/eslint/conventions/no-implicit-boolean.d.ts.map +1 -1
  236. package/build/src/rules/eslint/conventions/no-implicit-boolean.js +14 -14
  237. package/build/src/rules/eslint/conventions/no-implicit-boolean.js.map +1 -1
  238. package/build/src/rules/eslint/conventions/require-explicit-return.d.ts +6 -6
  239. package/build/src/rules/eslint/conventions/require-explicit-return.d.ts.map +1 -1
  240. package/build/src/rules/eslint/conventions/require-explicit-return.js +14 -14
  241. package/build/src/rules/eslint/conventions/require-explicit-return.js.map +1 -1
  242. package/build/src/rules/eslint/conventions/require-hash-private.d.ts +4 -4
  243. package/build/src/rules/eslint/conventions/require-hash-private.d.ts.map +1 -1
  244. package/build/src/rules/eslint/conventions/require-hash-private.js +3 -3
  245. package/build/src/rules/eslint/conventions/require-hash-private.js.map +1 -1
  246. package/build/src/rules/eslint/conventions/require-kebab-case-filename.d.ts +4 -4
  247. package/build/src/rules/eslint/conventions/require-kebab-case-filename.d.ts.map +1 -1
  248. package/build/src/rules/eslint/conventions/require-kebab-case-filename.js +4 -4
  249. package/build/src/rules/eslint/conventions/require-kebab-case-filename.js.map +1 -1
  250. package/build/src/rules/eslint/conventions/require-naming-convention.d.ts +16 -16
  251. package/build/src/rules/eslint/conventions/require-naming-convention.d.ts.map +1 -1
  252. package/build/src/rules/eslint/conventions/require-naming-convention.js +34 -31
  253. package/build/src/rules/eslint/conventions/require-naming-convention.js.map +1 -1
  254. package/build/src/rules/eslint/conventions/require-undefined-init.d.ts +3 -3
  255. package/build/src/rules/eslint/conventions/require-undefined-init.d.ts.map +1 -1
  256. package/build/src/rules/eslint/conventions/require-undefined-init.js +2 -2
  257. package/build/src/rules/eslint/conventions/require-undefined-init.js.map +1 -1
  258. package/build/src/rules/eslint/conventions/switch-case-blocks.d.ts +4 -4
  259. package/build/src/rules/eslint/conventions/switch-case-blocks.d.ts.map +1 -1
  260. package/build/src/rules/eslint/conventions/switch-case-blocks.js +3 -3
  261. package/build/src/rules/eslint/conventions/switch-case-blocks.js.map +1 -1
  262. package/build/src/rules/eslint/formatting/no-complex-arrow-concise.d.ts +5 -5
  263. package/build/src/rules/eslint/formatting/no-complex-arrow-concise.d.ts.map +1 -1
  264. package/build/src/rules/eslint/formatting/no-complex-arrow-concise.js +16 -16
  265. package/build/src/rules/eslint/formatting/no-complex-arrow-concise.js.map +1 -1
  266. package/build/src/rules/eslint/formatting/no-multiline-strings.d.ts +4 -4
  267. package/build/src/rules/eslint/formatting/no-multiline-strings.d.ts.map +1 -1
  268. package/build/src/rules/eslint/formatting/no-multiline-strings.js +19 -19
  269. package/build/src/rules/eslint/formatting/no-multiline-strings.js.map +1 -1
  270. package/build/src/rules/eslint/formatting/no-raw-text-in-code.d.ts +3 -3
  271. package/build/src/rules/eslint/formatting/no-raw-text-in-code.d.ts.map +1 -1
  272. package/build/src/rules/eslint/formatting/no-raw-text-in-code.js +2 -2
  273. package/build/src/rules/eslint/formatting/no-raw-text-in-code.js.map +1 -1
  274. package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.d.ts +3 -3
  275. package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.d.ts.map +1 -1
  276. package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.js +2 -2
  277. package/build/src/rules/eslint/formatting/no-ternary-in-template-literal.js.map +1 -1
  278. package/build/src/rules/eslint/formatting/require-import-order.d.ts +3 -3
  279. package/build/src/rules/eslint/formatting/require-import-order.d.ts.map +1 -1
  280. package/build/src/rules/eslint/formatting/require-import-order.js +6 -6
  281. package/build/src/rules/eslint/formatting/require-import-order.js.map +1 -1
  282. package/build/src/rules/eslint/formatting/require-multiline-condition-groups.d.ts +4 -4
  283. package/build/src/rules/eslint/formatting/require-multiline-condition-groups.d.ts.map +1 -1
  284. package/build/src/rules/eslint/formatting/require-multiline-condition-groups.js +5 -5
  285. package/build/src/rules/eslint/formatting/require-multiline-condition-groups.js.map +1 -1
  286. package/build/src/rules/eslint/formatting/require-multiline-conditions.d.ts +4 -4
  287. package/build/src/rules/eslint/formatting/require-multiline-conditions.d.ts.map +1 -1
  288. package/build/src/rules/eslint/formatting/require-multiline-conditions.js +5 -5
  289. package/build/src/rules/eslint/formatting/require-multiline-conditions.js.map +1 -1
  290. package/build/src/rules/eslint/formatting/require-padding-lines.d.ts +9 -9
  291. package/build/src/rules/eslint/formatting/require-padding-lines.d.ts.map +1 -1
  292. package/build/src/rules/eslint/formatting/require-padding-lines.js +20 -20
  293. package/build/src/rules/eslint/formatting/require-padding-lines.js.map +1 -1
  294. package/build/src/rules/eslint/formatting/require-ternary-parens.d.ts +3 -3
  295. package/build/src/rules/eslint/formatting/require-ternary-parens.d.ts.map +1 -1
  296. package/build/src/rules/eslint/formatting/require-ternary-parens.js +2 -2
  297. package/build/src/rules/eslint/formatting/require-ternary-parens.js.map +1 -1
  298. package/build/src/rules/eslint/index.d.ts +44 -44
  299. package/build/src/rules/eslint/index.d.ts.map +1 -1
  300. package/build/src/rules/eslint/index.js +44 -44
  301. package/build/src/rules/eslint/index.js.map +1 -1
  302. package/build/src/rules/eslint/jsdoc/require-jsdoc-body.d.ts +7 -7
  303. package/build/src/rules/eslint/jsdoc/require-jsdoc-body.d.ts.map +1 -1
  304. package/build/src/rules/eslint/jsdoc/require-jsdoc-body.js +7 -7
  305. package/build/src/rules/eslint/jsdoc/require-jsdoc-body.js.map +1 -1
  306. package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.d.ts +9 -7
  307. package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.d.ts.map +1 -1
  308. package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.js +115 -61
  309. package/build/src/rules/eslint/jsdoc/require-jsdoc-hierarchy.js.map +1 -1
  310. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.d.ts +3 -3
  311. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.d.ts.map +1 -1
  312. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.js +6 -6
  313. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-alignment.js.map +1 -1
  314. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.d.ts +3 -3
  315. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.d.ts.map +1 -1
  316. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.js +3 -3
  317. package/build/src/rules/eslint/jsdoc/require-jsdoc-param-name.js.map +1 -1
  318. package/build/src/rules/eslint/jsdoc/require-jsdoc-private.d.ts +3 -3
  319. package/build/src/rules/eslint/jsdoc/require-jsdoc-private.d.ts.map +1 -1
  320. package/build/src/rules/eslint/jsdoc/require-jsdoc-private.js +3 -3
  321. package/build/src/rules/eslint/jsdoc/require-jsdoc-private.js.map +1 -1
  322. package/build/src/rules/eslint/jsdoc/require-jsdoc-since.d.ts +3 -3
  323. package/build/src/rules/eslint/jsdoc/require-jsdoc-since.d.ts.map +1 -1
  324. package/build/src/rules/eslint/jsdoc/require-jsdoc-since.js +8 -8
  325. package/build/src/rules/eslint/jsdoc/require-jsdoc-since.js.map +1 -1
  326. package/build/src/rules/eslint/nova/no-logger-dev.d.ts +3 -3
  327. package/build/src/rules/eslint/nova/no-logger-dev.d.ts.map +1 -1
  328. package/build/src/rules/eslint/nova/no-logger-dev.js +5 -5
  329. package/build/src/rules/eslint/nova/no-logger-dev.js.map +1 -1
  330. package/build/src/rules/eslint/patterns/no-assign-then-return.d.ts +3 -3
  331. package/build/src/rules/eslint/patterns/no-assign-then-return.d.ts.map +1 -1
  332. package/build/src/rules/eslint/patterns/no-assign-then-return.js +2 -2
  333. package/build/src/rules/eslint/patterns/no-assign-then-return.js.map +1 -1
  334. package/build/src/rules/eslint/patterns/no-await-in-loop.d.ts +7 -7
  335. package/build/src/rules/eslint/patterns/no-await-in-loop.d.ts.map +1 -1
  336. package/build/src/rules/eslint/patterns/no-await-in-loop.js +4 -4
  337. package/build/src/rules/eslint/patterns/no-await-in-loop.js.map +1 -1
  338. package/build/src/rules/eslint/patterns/no-boolean-var-for-if.d.ts +3 -3
  339. package/build/src/rules/eslint/patterns/no-boolean-var-for-if.d.ts.map +1 -1
  340. package/build/src/rules/eslint/patterns/no-boolean-var-for-if.js +2 -2
  341. package/build/src/rules/eslint/patterns/no-boolean-var-for-if.js.map +1 -1
  342. package/build/src/rules/eslint/patterns/no-bracket-assignment.d.ts +3 -3
  343. package/build/src/rules/eslint/patterns/no-bracket-assignment.d.ts.map +1 -1
  344. package/build/src/rules/eslint/patterns/no-bracket-assignment.js +2 -2
  345. package/build/src/rules/eslint/patterns/no-bracket-assignment.js.map +1 -1
  346. package/build/src/rules/eslint/patterns/no-bracket-method-call.d.ts +4 -4
  347. package/build/src/rules/eslint/patterns/no-bracket-method-call.d.ts.map +1 -1
  348. package/build/src/rules/eslint/patterns/no-bracket-method-call.js +2 -2
  349. package/build/src/rules/eslint/patterns/no-bracket-method-call.js.map +1 -1
  350. package/build/src/rules/eslint/patterns/no-template-curly-in-string.d.ts +3 -3
  351. package/build/src/rules/eslint/patterns/no-template-curly-in-string.d.ts.map +1 -1
  352. package/build/src/rules/eslint/patterns/no-template-curly-in-string.js +2 -2
  353. package/build/src/rules/eslint/patterns/no-template-curly-in-string.js.map +1 -1
  354. package/build/src/rules/eslint/patterns/no-use-before-define.d.ts +7 -7
  355. package/build/src/rules/eslint/patterns/no-use-before-define.d.ts.map +1 -1
  356. package/build/src/rules/eslint/patterns/no-use-before-define.js +2 -2
  357. package/build/src/rules/eslint/patterns/no-use-before-define.js.map +1 -1
  358. package/build/src/rules/eslint/regex/no-regex-literal-flags.d.ts +3 -3
  359. package/build/src/rules/eslint/regex/no-regex-literal-flags.d.ts.map +1 -1
  360. package/build/src/rules/eslint/regex/no-regex-literal-flags.js +2 -2
  361. package/build/src/rules/eslint/regex/no-regex-literal-flags.js.map +1 -1
  362. package/build/src/rules/eslint/regex/no-regex-literals.d.ts +4 -4
  363. package/build/src/rules/eslint/regex/no-regex-literals.d.ts.map +1 -1
  364. package/build/src/rules/eslint/regex/no-regex-literals.js +2 -2
  365. package/build/src/rules/eslint/regex/no-regex-literals.js.map +1 -1
  366. package/build/src/rules/eslint/safety/no-script-url.d.ts +4 -4
  367. package/build/src/rules/eslint/safety/no-script-url.d.ts.map +1 -1
  368. package/build/src/rules/eslint/safety/no-script-url.js +2 -2
  369. package/build/src/rules/eslint/safety/no-script-url.js.map +1 -1
  370. package/build/src/rules/eslint/syntax/no-destructuring.d.ts +8 -8
  371. package/build/src/rules/eslint/syntax/no-destructuring.d.ts.map +1 -1
  372. package/build/src/rules/eslint/syntax/no-destructuring.js +10 -10
  373. package/build/src/rules/eslint/syntax/no-destructuring.js.map +1 -1
  374. package/build/src/rules/eslint/syntax/no-numeric-literals.d.ts +6 -6
  375. package/build/src/rules/eslint/syntax/no-numeric-literals.d.ts.map +1 -1
  376. package/build/src/rules/eslint/syntax/no-numeric-literals.js +2 -2
  377. package/build/src/rules/eslint/syntax/no-numeric-literals.js.map +1 -1
  378. package/build/src/rules/eslint/syntax/no-optional-chaining.d.ts +3 -3
  379. package/build/src/rules/eslint/syntax/no-optional-chaining.d.ts.map +1 -1
  380. package/build/src/rules/eslint/syntax/no-optional-chaining.js +2 -2
  381. package/build/src/rules/eslint/syntax/no-optional-chaining.js.map +1 -1
  382. package/build/src/rules/eslint/syntax/no-rest-params.d.ts +4 -4
  383. package/build/src/rules/eslint/syntax/no-rest-params.d.ts.map +1 -1
  384. package/build/src/rules/eslint/syntax/no-rest-params.js +8 -8
  385. package/build/src/rules/eslint/syntax/no-rest-params.js.map +1 -1
  386. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.d.ts +3 -3
  387. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.d.ts.map +1 -1
  388. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.js +2 -2
  389. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.js.map +1 -1
  390. package/build/src/rules/eslint/typescript/no-explicit-any.d.ts +3 -3
  391. package/build/src/rules/eslint/typescript/no-explicit-any.d.ts.map +1 -1
  392. package/build/src/rules/eslint/typescript/no-explicit-any.js +2 -2
  393. package/build/src/rules/eslint/typescript/no-explicit-any.js.map +1 -1
  394. package/build/src/rules/eslint/typescript/no-inline-type-annotation.d.ts +3 -3
  395. package/build/src/rules/eslint/typescript/no-inline-type-annotation.d.ts.map +1 -1
  396. package/build/src/rules/eslint/typescript/no-inline-type-annotation.js +9 -9
  397. package/build/src/rules/eslint/typescript/no-inline-type-annotation.js.map +1 -1
  398. package/build/src/rules/eslint/typescript/no-shared-type-import.d.ts +4 -4
  399. package/build/src/rules/eslint/typescript/no-shared-type-import.d.ts.map +1 -1
  400. package/build/src/rules/eslint/typescript/no-shared-type-import.js +2 -2
  401. package/build/src/rules/eslint/typescript/no-shared-type-import.js.map +1 -1
  402. package/build/src/rules/eslint/typescript/require-bracket-property-access.d.ts +4 -4
  403. package/build/src/rules/eslint/typescript/require-bracket-property-access.d.ts.map +1 -1
  404. package/build/src/rules/eslint/typescript/require-bracket-property-access.js +2 -2
  405. package/build/src/rules/eslint/typescript/require-bracket-property-access.js.map +1 -1
  406. package/build/src/rules/eslint/typescript/require-type-naming.d.ts +6 -4
  407. package/build/src/rules/eslint/typescript/require-type-naming.d.ts.map +1 -1
  408. package/build/src/rules/eslint/typescript/require-type-naming.js +54 -8
  409. package/build/src/rules/eslint/typescript/require-type-naming.js.map +1 -1
  410. package/build/src/toolkit/bootstrap.d.ts +10 -10
  411. package/build/src/toolkit/bootstrap.d.ts.map +1 -1
  412. package/build/src/toolkit/bootstrap.js +33 -33
  413. package/build/src/toolkit/bootstrap.js.map +1 -1
  414. package/build/src/toolkit/cli-header.d.ts +4 -4
  415. package/build/src/toolkit/cli-header.d.ts.map +1 -1
  416. package/build/src/toolkit/cli-header.js +22 -22
  417. package/build/src/toolkit/cli-header.js.map +1 -1
  418. package/build/src/toolkit/logger.d.ts +9 -9
  419. package/build/src/toolkit/logger.d.ts.map +1 -1
  420. package/build/src/toolkit/logger.js +16 -16
  421. package/build/src/toolkit/logger.js.map +1 -1
  422. package/build/src/toolkit/markdown-table.d.ts +6 -6
  423. package/build/src/toolkit/markdown-table.d.ts.map +1 -1
  424. package/build/src/toolkit/markdown-table.js +2 -2
  425. package/build/src/toolkit/markdown-table.js.map +1 -1
  426. package/build/src/types/api/node-releases.d.ts +14 -14
  427. package/build/src/types/api/spdx-licenses.d.ts +17 -17
  428. package/build/src/types/cli/generate/github/funding.d.ts +28 -28
  429. package/build/src/types/cli/generate/github/issue-template.d.ts +87 -71
  430. package/build/src/types/cli/generate/github/workflows.d.ts +359 -311
  431. package/build/src/types/cli/generate/must-haves/agent-conventions.d.ts +28 -22
  432. package/build/src/types/cli/generate/must-haves/dotenv.d.ts +208 -206
  433. package/build/src/types/cli/generate/must-haves/editorconfig.d.ts +16 -16
  434. package/build/src/types/cli/generate/must-haves/gitignore.d.ts +188 -156
  435. package/build/src/types/cli/generate/must-haves/license.d.ts +28 -26
  436. package/build/src/types/cli/generate/must-haves/read-me.d.ts +105 -95
  437. package/build/src/types/cli/index.d.ts +73 -84
  438. package/build/src/types/cli/recipe/github/handle-gh-failure.d.ts +18 -0
  439. package/build/src/types/cli/recipe/github/sync-features.d.ts +67 -0
  440. package/build/src/types/cli/recipe/github/sync-identity.d.ts +107 -0
  441. package/build/src/types/cli/recipe/github/sync-policies.d.ts +70 -0
  442. package/build/src/types/cli/recipe/index.d.ts +21 -16
  443. package/build/src/types/cli/recipe/package-json/cleanup.d.ts +57 -55
  444. package/build/src/types/cli/recipe/package-json/normalize-artifacts.d.ts +44 -44
  445. package/build/src/types/cli/recipe/package-json/normalize-bundler.d.ts +36 -36
  446. package/build/src/types/cli/recipe/package-json/normalize-dependencies.d.ts +65 -65
  447. package/build/src/types/cli/recipe/package-json/normalize-modules.d.ts +37 -35
  448. package/build/src/types/cli/recipe/package-json/normalize-tooling.d.ts +39 -39
  449. package/build/src/types/cli/recipe/package-json/sync-environment.d.ts +60 -60
  450. package/build/src/types/cli/recipe/package-json/sync-identity.d.ts +51 -51
  451. package/build/src/types/cli/recipe/package-json/sync-ownership.d.ts +78 -78
  452. package/build/src/types/cli/scaffold/app/expressjs.d.ts +10 -10
  453. package/build/src/types/cli/scaffold/app/nextjs.d.ts +10 -10
  454. package/build/src/types/cli/scaffold/app/vite.d.ts +10 -10
  455. package/build/src/types/cli/scaffold/app/workers.d.ts +10 -10
  456. package/build/src/types/cli/scaffold/docs/docusaurus.d.ts +10 -10
  457. package/build/src/types/cli/scaffold/starter/base.d.ts +27 -27
  458. package/build/src/types/cli/utility/changelog.d.ts +189 -180
  459. package/build/src/types/cli/utility/initialize.d.ts +1135 -690
  460. package/build/src/types/cli/utility/run-recipes.d.ts +32 -11
  461. package/build/src/types/cli/utility/run-scripts.d.ts +126 -52
  462. package/build/src/types/cli/utility/transpile.d.ts +30 -30
  463. package/build/src/types/cli/utility/type-check.d.ts +30 -30
  464. package/build/src/types/cli/utility/version.d.ts +130 -130
  465. package/build/src/types/lib/constants.d.ts +8 -1
  466. package/build/src/types/lib/item.d.ts +158 -149
  467. package/build/src/types/lib/nova-config.d.ts +379 -191
  468. package/build/src/types/lib/regex.d.ts +762 -0
  469. package/build/src/types/lib/scaffold.d.ts +176 -149
  470. package/build/src/types/lib/utility.d.ts +369 -220
  471. package/build/src/types/lib/workflow-templates.d.ts +61 -56
  472. package/build/src/types/presets/eslint/dx-code-style.d.ts +1 -1
  473. package/build/src/types/presets/eslint/dx-ignore.d.ts +1 -1
  474. package/build/src/types/presets/eslint/fw-docusaurus.d.ts +1 -1
  475. package/build/src/types/presets/eslint/fw-expressjs.d.ts +1 -1
  476. package/build/src/types/presets/eslint/fw-nextjs.d.ts +1 -1
  477. package/build/src/types/presets/eslint/lang-javascript.d.ts +1 -1
  478. package/build/src/types/presets/eslint/lang-mdx.d.ts +1 -1
  479. package/build/src/types/presets/eslint/lang-typescript.d.ts +1 -1
  480. package/build/src/types/presets/eslint/runtime-browser.d.ts +1 -1
  481. package/build/src/types/presets/eslint/runtime-cloudflare-workers.d.ts +1 -1
  482. package/build/src/types/presets/eslint/runtime-edge.d.ts +1 -1
  483. package/build/src/types/presets/eslint/runtime-node.d.ts +1 -1
  484. package/build/src/types/presets/eslint/runtime-service-worker.d.ts +1 -1
  485. package/build/src/types/presets/eslint/runtime-web-worker.d.ts +1 -1
  486. package/build/src/types/presets/eslint/tool-vite.d.ts +1 -1
  487. package/build/src/types/rules/eslint/conventions/no-default-export-declaration.d.ts +30 -13
  488. package/build/src/types/rules/eslint/conventions/no-implicit-boolean.d.ts +84 -25
  489. package/build/src/types/rules/eslint/conventions/require-explicit-return.d.ts +47 -42
  490. package/build/src/types/rules/eslint/conventions/require-hash-private.d.ts +35 -12
  491. package/build/src/types/rules/eslint/conventions/require-kebab-case-filename.d.ts +35 -29
  492. package/build/src/types/rules/eslint/conventions/require-naming-convention.d.ts +212 -115
  493. package/build/src/types/rules/eslint/conventions/require-undefined-init.d.ts +34 -11
  494. package/build/src/types/rules/eslint/conventions/switch-case-blocks.d.ts +41 -18
  495. package/build/src/types/rules/eslint/formatting/no-complex-arrow-concise.d.ts +44 -30
  496. package/build/src/types/rules/eslint/formatting/no-multiline-strings.d.ts +67 -44
  497. package/build/src/types/rules/eslint/formatting/no-raw-text-in-code.d.ts +24 -10
  498. package/build/src/types/rules/eslint/formatting/no-ternary-in-template-literal.d.ts +23 -9
  499. package/build/src/types/rules/eslint/formatting/require-import-order.d.ts +51 -39
  500. package/build/src/types/rules/eslint/formatting/require-multiline-condition-groups.d.ts +42 -26
  501. package/build/src/types/rules/eslint/formatting/require-multiline-conditions.d.ts +36 -20
  502. package/build/src/types/rules/eslint/formatting/require-padding-lines.d.ts +144 -103
  503. package/build/src/types/rules/eslint/formatting/require-ternary-parens.d.ts +35 -12
  504. package/build/src/types/rules/eslint/jsdoc/require-jsdoc-body.d.ts +65 -29
  505. package/build/src/types/rules/eslint/jsdoc/require-jsdoc-hierarchy.d.ts +308 -134
  506. package/build/src/types/rules/eslint/jsdoc/require-jsdoc-param-alignment.d.ts +59 -52
  507. package/build/src/types/rules/eslint/jsdoc/require-jsdoc-param-name.d.ts +41 -26
  508. package/build/src/types/rules/eslint/jsdoc/require-jsdoc-private.d.ts +49 -17
  509. package/build/src/types/rules/eslint/jsdoc/require-jsdoc-since.d.ts +79 -11
  510. package/build/src/types/rules/eslint/nova/no-logger-dev.d.ts +35 -25
  511. package/build/src/types/rules/eslint/patterns/no-assign-then-return.d.ts +40 -17
  512. package/build/src/types/rules/eslint/patterns/no-await-in-loop.d.ts +53 -45
  513. package/build/src/types/rules/eslint/patterns/no-boolean-var-for-if.d.ts +34 -20
  514. package/build/src/types/rules/eslint/patterns/no-bracket-assignment.d.ts +36 -13
  515. package/build/src/types/rules/eslint/patterns/no-bracket-method-call.d.ts +43 -20
  516. package/build/src/types/rules/eslint/patterns/no-template-curly-in-string.d.ts +26 -12
  517. package/build/src/types/rules/eslint/patterns/no-use-before-define.d.ts +59 -45
  518. package/build/src/types/rules/eslint/regex/no-regex-literal-flags.d.ts +23 -9
  519. package/build/src/types/rules/eslint/regex/no-regex-literals.d.ts +31 -17
  520. package/build/src/types/rules/eslint/safety/no-script-url.d.ts +29 -15
  521. package/build/src/types/rules/eslint/syntax/no-destructuring.d.ts +61 -58
  522. package/build/src/types/rules/eslint/syntax/no-numeric-literals.d.ts +43 -29
  523. package/build/src/types/rules/eslint/syntax/no-optional-chaining.d.ts +23 -9
  524. package/build/src/types/rules/eslint/syntax/no-rest-params.d.ts +63 -31
  525. package/build/src/types/rules/eslint/typescript/no-catch-unknown-annotation.d.ts +34 -11
  526. package/build/src/types/rules/eslint/typescript/no-explicit-any.d.ts +23 -9
  527. package/build/src/types/rules/eslint/typescript/no-inline-type-annotation.d.ts +58 -32
  528. package/build/src/types/rules/eslint/typescript/no-shared-type-import.d.ts +32 -18
  529. package/build/src/types/rules/eslint/typescript/require-bracket-property-access.d.ts +50 -22
  530. package/build/src/types/rules/eslint/typescript/require-type-naming.d.ts +87 -20
  531. package/build/src/types/shared.d.ts +410 -365
  532. package/build/src/types/tests/api/node-releases.test.d.ts +87 -6
  533. package/build/src/types/tests/api/spdx-licenses.test.d.ts +48 -8
  534. package/build/src/types/tests/cli/generate/github/funding.test.d.ts +25 -7
  535. package/build/src/types/tests/cli/generate/github/issue-template.test.d.ts +25 -7
  536. package/build/src/types/tests/cli/generate/github/workflows-helpers.test.d.ts +193 -30
  537. package/build/src/types/tests/cli/generate/github/workflows.test.d.ts +550 -35
  538. package/build/src/types/tests/cli/generate/must-haves/agent-conventions.test.d.ts +39 -14
  539. package/build/src/types/tests/cli/generate/must-haves/dotenv.test.d.ts +26 -8
  540. package/build/src/types/tests/cli/generate/must-haves/editorconfig.test.d.ts +22 -6
  541. package/build/src/types/tests/cli/generate/must-haves/gitignore.test.d.ts +24 -6
  542. package/build/src/types/tests/cli/generate/must-haves/license.test.d.ts +150 -12
  543. package/build/src/types/tests/cli/generate/must-haves/read-me.test.d.ts +211 -23
  544. package/build/src/types/tests/cli/recipe/github/handle-gh-failure.test.d.ts +96 -0
  545. package/build/src/types/tests/cli/recipe/github/sync-features.test.d.ts +357 -0
  546. package/build/src/types/tests/cli/recipe/github/sync-identity.test.d.ts +475 -0
  547. package/build/src/types/tests/cli/recipe/github/sync-policies.test.d.ts +408 -0
  548. package/build/src/types/tests/cli/recipe/package-json/cleanup.test.d.ts +159 -20
  549. package/build/src/types/tests/cli/recipe/package-json/normalize-artifacts.test.d.ts +102 -15
  550. package/build/src/types/tests/cli/recipe/package-json/normalize-bundler.test.d.ts +102 -15
  551. package/build/src/types/tests/cli/recipe/package-json/normalize-dependencies.test.d.ts +106 -19
  552. package/build/src/types/tests/cli/recipe/package-json/normalize-modules.test.d.ts +101 -14
  553. package/build/src/types/tests/cli/recipe/package-json/normalize-tooling.test.d.ts +126 -14
  554. package/build/src/types/tests/cli/recipe/package-json/sync-environment.test.d.ts +101 -14
  555. package/build/src/types/tests/cli/recipe/package-json/sync-identity.test.d.ts +101 -14
  556. package/build/src/types/tests/cli/recipe/package-json/sync-ownership.test.d.ts +101 -14
  557. package/build/src/types/tests/cli/scaffold/app/expressjs.test.d.ts +59 -18
  558. package/build/src/types/tests/cli/scaffold/app/nextjs.test.d.ts +62 -19
  559. package/build/src/types/tests/cli/scaffold/app/vite.test.d.ts +60 -19
  560. package/build/src/types/tests/cli/scaffold/app/workers.test.d.ts +59 -18
  561. package/build/src/types/tests/cli/scaffold/docs/docusaurus.test.d.ts +59 -18
  562. package/build/src/types/tests/cli/scaffold/starter/base.test.d.ts +55 -18
  563. package/build/src/types/tests/cli/utility/changelog.test.d.ts +161 -32
  564. package/build/src/types/tests/cli/utility/initialize.test.d.ts +211 -5
  565. package/build/src/types/tests/cli/utility/run-recipes.test.d.ts +87 -9
  566. package/build/src/types/tests/cli/utility/run-scripts.test.d.ts +124 -24
  567. package/build/src/types/tests/cli/utility/transpile.test.d.ts +23 -11
  568. package/build/src/types/tests/cli/utility/type-check.test.d.ts +34 -9
  569. package/build/src/types/tests/cli/utility/version.test.d.ts +33 -4
  570. package/build/src/types/tests/lib/item.test.d.ts +191 -37
  571. package/build/src/types/tests/lib/nova-config.test.d.ts +1032 -69
  572. package/build/src/types/tests/lib/regex.test.d.ts +453 -27
  573. package/build/src/types/tests/lib/scaffold.test.d.ts +55 -12
  574. package/build/src/types/tests/lib/schema.test.d.ts +171 -16
  575. package/build/src/types/tests/lib/utility.test.d.ts +1131 -164
  576. package/build/src/types/tests/lib/workflow-templates.test.d.ts +17 -17
  577. package/build/src/types/tests/rules/eslint/conventions/no-default-export-declaration.test.d.ts +1 -1
  578. package/build/src/types/tests/rules/eslint/conventions/no-implicit-boolean.test.d.ts +1 -1
  579. package/build/src/types/tests/rules/eslint/conventions/require-explicit-return.test.d.ts +1 -1
  580. package/build/src/types/tests/rules/eslint/conventions/require-hash-private.test.d.ts +1 -1
  581. package/build/src/types/tests/rules/eslint/conventions/require-kebab-case-filename.test.d.ts +1 -1
  582. package/build/src/types/tests/rules/eslint/conventions/require-naming-convention.test.d.ts +1 -1
  583. package/build/src/types/tests/rules/eslint/conventions/require-undefined-init.test.d.ts +1 -1
  584. package/build/src/types/tests/rules/eslint/conventions/switch-case-blocks.test.d.ts +1 -1
  585. package/build/src/types/tests/rules/eslint/formatting/no-complex-arrow-concise.test.d.ts +1 -1
  586. package/build/src/types/tests/rules/eslint/formatting/no-multiline-strings.test.d.ts +1 -1
  587. package/build/src/types/tests/rules/eslint/formatting/no-raw-text-in-code.test.d.ts +1 -1
  588. package/build/src/types/tests/rules/eslint/formatting/no-ternary-in-template-literal.test.d.ts +1 -1
  589. package/build/src/types/tests/rules/eslint/formatting/require-import-order.test.d.ts +1 -1
  590. package/build/src/types/tests/rules/eslint/formatting/require-multiline-condition-groups.test.d.ts +1 -1
  591. package/build/src/types/tests/rules/eslint/formatting/require-multiline-conditions.test.d.ts +1 -1
  592. package/build/src/types/tests/rules/eslint/formatting/require-padding-lines.test.d.ts +1 -1
  593. package/build/src/types/tests/rules/eslint/formatting/require-ternary-parens.test.d.ts +1 -1
  594. package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-body.test.d.ts +1 -1
  595. package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-hierarchy.test.d.ts +1 -1
  596. package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-param-alignment.test.d.ts +1 -1
  597. package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-param-name.test.d.ts +1 -1
  598. package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-private.test.d.ts +1 -1
  599. package/build/src/types/tests/rules/eslint/jsdoc/require-jsdoc-since.test.d.ts +1 -1
  600. package/build/src/types/tests/rules/eslint/nova/no-logger-dev.test.d.ts +1 -1
  601. package/build/src/types/tests/rules/eslint/patterns/no-assign-then-return.test.d.ts +1 -1
  602. package/build/src/types/tests/rules/eslint/patterns/no-await-in-loop.test.d.ts +1 -1
  603. package/build/src/types/tests/rules/eslint/patterns/no-boolean-var-for-if.test.d.ts +1 -1
  604. package/build/src/types/tests/rules/eslint/patterns/no-bracket-assignment.test.d.ts +1 -1
  605. package/build/src/types/tests/rules/eslint/patterns/no-bracket-method-call.test.d.ts +1 -1
  606. package/build/src/types/tests/rules/eslint/patterns/no-template-curly-in-string.test.d.ts +1 -1
  607. package/build/src/types/tests/rules/eslint/patterns/no-use-before-define.test.d.ts +1 -1
  608. package/build/src/types/tests/rules/eslint/regex/no-regex-literal-flags.test.d.ts +1 -1
  609. package/build/src/types/tests/rules/eslint/regex/no-regex-literals.test.d.ts +1 -1
  610. package/build/src/types/tests/rules/eslint/safety/no-script-url.test.d.ts +1 -1
  611. package/build/src/types/tests/rules/eslint/syntax/no-destructuring.test.d.ts +1 -1
  612. package/build/src/types/tests/rules/eslint/syntax/no-numeric-literals.test.d.ts +1 -1
  613. package/build/src/types/tests/rules/eslint/syntax/no-optional-chaining.test.d.ts +1 -1
  614. package/build/src/types/tests/rules/eslint/syntax/no-rest-params.test.d.ts +1 -1
  615. package/build/src/types/tests/rules/eslint/typescript/no-catch-unknown-annotation.test.d.ts +1 -1
  616. package/build/src/types/tests/rules/eslint/typescript/no-explicit-any.test.d.ts +1 -1
  617. package/build/src/types/tests/rules/eslint/typescript/no-inline-type-annotation.test.d.ts +1 -1
  618. package/build/src/types/tests/rules/eslint/typescript/no-shared-type-import.test.d.ts +1 -1
  619. package/build/src/types/tests/rules/eslint/typescript/require-bracket-property-access.test.d.ts +3 -3
  620. package/build/src/types/tests/rules/eslint/typescript/require-type-naming.test.d.ts +1 -1
  621. package/build/src/types/tests/toolkit/bootstrap.test.d.ts +155 -40
  622. package/build/src/types/tests/toolkit/cli-header.test.d.ts +135 -22
  623. package/build/src/types/tests/toolkit/logger.test.d.ts +113 -5
  624. package/build/src/types/tests/toolkit/markdown-table.test.d.ts +150 -27
  625. package/build/src/types/tests/type-declarations.test.d.ts +4683 -300
  626. package/build/src/types/toolkit/bootstrap.d.ts +71 -47
  627. package/build/src/types/toolkit/cli-header.d.ts +98 -88
  628. package/build/src/types/toolkit/logger.d.ts +98 -53
  629. package/build/src/types/toolkit/markdown-table.d.ts +74 -72
  630. package/build/templates/generators/github/workflows/publish/targets/aws-amplify-nextjs.yml +1 -1
  631. package/build/templates/generators/github/workflows/publish/targets/cloudflare-pages-docusaurus.yml +1 -1
  632. package/build/templates/generators/github/workflows/publish/targets/github-action.yml +121 -0
  633. package/build/templates/generators/github/workflows/publish/targets/github-packages.yml +1 -1
  634. package/build/templates/generators/github/workflows/publish/targets/github-pages-docusaurus.yml +1 -1
  635. package/build/templates/generators/github/workflows/publish/targets/npm.yml +1 -1
  636. package/build/templates/generators/github/workflows/publish/targets/vercel-nextjs.yml +1 -1
  637. package/build/templates/generators/must-haves/agent-conventions/AGENTS.md +1 -0
  638. package/build/templates/generators/must-haves/agent-conventions/CLAUDE.md +1 -0
  639. package/build/templates/generators/must-haves/agent-conventions/PROJECT_RULES.md +1 -1
  640. package/build/templates/generators/must-haves/agent-conventions/conventions/typescript.md +412 -148
  641. package/build/templates/generators/must-haves/agent-conventions/conventions/universal.md +27 -3
  642. package/build/templates/generators/must-haves/agent-conventions/cursorrules +1 -0
  643. package/package.json +1 -1
@@ -3,15 +3,15 @@ import { join, relative, sep } from 'path';
3
3
  import chalk from 'chalk';
4
4
  import prompts from 'prompts';
5
5
  import { libItemAllowedPoliciesByRole, libItemAllowedRecipes, libItemSyncRoles, libItemValidEntityRoles, } from '../../lib/item.js';
6
- import { LibNovaConfig } from '../../lib/nova-config.js';
6
+ import { Runner as LibNovaConfig } from '../../lib/nova-config.js';
7
7
  import { LIB_REGEX_PATTERN_EMAIL_SIMPLE, LIB_REGEX_PATTERN_SLUG_SCOPED, LIB_REGEX_PATTERN_SLUG_SIMPLE, LIB_REGEX_PATTERN_YML_EXTENSION, } from '../../lib/regex.js';
8
8
  import { discoverPathsWithFile, pathExists, resolveTemplatePath } from '../../lib/utility.js';
9
9
  import { libWorkflowTemplatesMetadata } from '../../lib/workflow-templates.js';
10
10
  import { Logger } from '../../toolkit/index.js';
11
- export class CliUtilityInitialize {
11
+ export class Runner {
12
12
  static async run(options) {
13
13
  const currentDirectory = process.cwd();
14
- const isProjectRoot = await CliUtilityInitialize.checkPath(currentDirectory);
14
+ const isProjectRoot = await Runner.checkPath(currentDirectory);
15
15
  if (isProjectRoot !== true) {
16
16
  process.exitCode = 1;
17
17
  return;
@@ -20,23 +20,23 @@ export class CliUtilityInitialize {
20
20
  const isReplaceFile = options['replaceFile'] === true;
21
21
  if (isDryRun === true) {
22
22
  Logger.customize({
23
- name: 'CliUtilityInitialize.run',
23
+ name: 'Runner.run',
24
24
  purpose: 'options',
25
25
  }).warn('Dry run enabled. File changes will not be made in this session.');
26
26
  }
27
27
  if (isReplaceFile === true) {
28
28
  const replaceFileNotice = (isDryRun === true) ? 'This option has no effect during a dry run session.' : 'Backup file will not be created.';
29
29
  Logger.customize({
30
- name: 'CliUtilityInitialize.run',
30
+ name: 'Runner.run',
31
31
  purpose: 'options',
32
32
  }).warn(`Replace file enabled. ${replaceFileNotice}`);
33
33
  }
34
34
  const novaConfig = new LibNovaConfig();
35
35
  const workingFile = await novaConfig.load();
36
- const promptFlowResult = await CliUtilityInitialize.promptFlow(workingFile);
36
+ const promptFlowResult = await Runner.promptFlow(workingFile);
37
37
  if (promptFlowResult === 'cancel') {
38
38
  Logger.customize({
39
- name: 'CliUtilityInitialize.run',
39
+ name: 'Runner.run',
40
40
  purpose: 'promptFlow',
41
41
  }).debug('Prompt flow exited without saving.');
42
42
  return;
@@ -44,7 +44,7 @@ export class CliUtilityInitialize {
44
44
  novaConfig.set(workingFile);
45
45
  if (isDryRun === true) {
46
46
  Logger.customize({
47
- name: 'CliUtilityInitialize.run',
47
+ name: 'Runner.run',
48
48
  purpose: 'promptFlow',
49
49
  }).debug('Dry run enabled. Skipping save operation.');
50
50
  return;
@@ -52,37 +52,48 @@ export class CliUtilityInitialize {
52
52
  await novaConfig.save(isReplaceFile);
53
53
  return;
54
54
  }
55
+ static isNonEmptyLiteralInput(value) {
56
+ if (typeof value === 'string' && value.trim() !== '') {
57
+ return true;
58
+ }
59
+ return 'This field is required.';
60
+ }
55
61
  static async promptFlow(config) {
56
62
  const category = {
57
63
  project: {
58
64
  label: 'Project',
59
65
  description: 'Configure project metadata (name, description, keywords).',
60
- handler: CliUtilityInitialize['promptProject'],
66
+ handler: Runner['promptProject'],
61
67
  },
62
68
  entities: {
63
69
  label: 'Entities',
64
70
  description: 'Manage entities, their roles, and contact information.',
65
- handler: CliUtilityInitialize['promptEntities'],
71
+ handler: Runner['promptEntities'],
66
72
  },
67
73
  emails: {
68
74
  label: 'Emails',
69
75
  description: 'Configure project emails (bugs, etc.).',
70
- handler: CliUtilityInitialize['promptEmails'],
76
+ handler: Runner['promptEmails'],
77
+ },
78
+ github: {
79
+ label: 'GitHub',
80
+ description: 'Configure GitHub repository settings, recipes, and policies.',
81
+ handler: Runner['promptGithub'],
71
82
  },
72
83
  workflows: {
73
84
  label: 'Workflows',
74
85
  description: 'Configure workflow templates and settings.',
75
- handler: CliUtilityInitialize['promptWorkflows'],
86
+ handler: Runner['promptWorkflows'],
76
87
  },
77
88
  urls: {
78
89
  label: 'URLs',
79
90
  description: 'Configure project URLs (homepage, repository, fund sources, etc.).',
80
- handler: CliUtilityInitialize['promptUrls'],
91
+ handler: Runner['promptUrls'],
81
92
  },
82
93
  workspaces: {
83
94
  label: 'Workspaces',
84
95
  description: 'Review workspace packages, assigning roles and policies.',
85
- handler: CliUtilityInitialize['promptWorkspaces'],
96
+ handler: Runner['promptWorkspaces'],
86
97
  },
87
98
  };
88
99
  while (true) {
@@ -102,7 +113,7 @@ export class CliUtilityInitialize {
102
113
  description: 'Exit without persisting any changes.',
103
114
  value: 'cancel',
104
115
  });
105
- const menuOutput = await CliUtilityInitialize.promptWithCancel({
116
+ const menuOutput = await Runner.promptWithCancel({
106
117
  type: 'select',
107
118
  name: 'action',
108
119
  message: 'Select a Nova configuration category to edit.',
@@ -138,52 +149,67 @@ export class CliUtilityInitialize {
138
149
  const projectName = (existingProjectName !== undefined) ? { ...existingProjectName } : {};
139
150
  const projectDescription = (existingProjectDescription !== undefined) ? { ...existingProjectDescription } : {};
140
151
  const projectKeywords = (existingProjectKeywords !== undefined) ? [...existingProjectKeywords] : [];
141
- const questionsOutput = await CliUtilityInitialize.promptWithCancel([
152
+ const validateProjectNameTitle = (projectNameTitleValue) => {
153
+ return Runner.normalizeText(projectNameTitleValue, Infinity)['result'];
154
+ };
155
+ const validateProjectNameSlug = (projectNameSlugValue) => {
156
+ return Runner.normalizeProjectSlug(projectNameSlugValue)['result'];
157
+ };
158
+ const validateProjectDescriptionShort = (projectDescriptionShortValue) => {
159
+ return Runner.normalizeText(projectDescriptionShortValue, Infinity)['result'];
160
+ };
161
+ const validateProjectDescriptionLong = (projectDescriptionLongValue) => {
162
+ return Runner.normalizeText(projectDescriptionLongValue, Infinity)['result'];
163
+ };
164
+ const validateProjectKeywords = (projectKeywordsValue) => {
165
+ return Runner.normalizeTextArray(projectKeywordsValue, 50)['result'];
166
+ };
167
+ const questionsOutput = await Runner.promptWithCancel([
142
168
  {
143
169
  type: 'text',
144
170
  name: 'projectNameTitle',
145
171
  message: 'Project title (display name)',
146
172
  initial: projectName['title'] ?? '',
147
- validate: (value) => CliUtilityInitialize.normalizeText(value, Infinity)['result'],
173
+ validate: validateProjectNameTitle,
148
174
  },
149
175
  {
150
176
  type: 'text',
151
177
  name: 'projectNameSlug',
152
178
  message: 'Project slug (package name)',
153
179
  initial: projectName['slug'] ?? '',
154
- validate: (value) => CliUtilityInitialize.normalizeProjectSlug(value)['result'],
180
+ validate: validateProjectNameSlug,
155
181
  },
156
182
  {
157
183
  type: 'text',
158
184
  name: 'projectDescriptionShort',
159
185
  message: 'Short description',
160
186
  initial: projectDescription['short'] ?? '',
161
- validate: (value) => CliUtilityInitialize.normalizeText(value, Infinity)['result'],
187
+ validate: validateProjectDescriptionShort,
162
188
  },
163
189
  {
164
190
  type: 'text',
165
191
  name: 'projectDescriptionLong',
166
192
  message: 'Long description',
167
193
  initial: projectDescription['long'] ?? '',
168
- validate: (value) => CliUtilityInitialize.normalizeText(value, Infinity)['result'],
194
+ validate: validateProjectDescriptionLong,
169
195
  },
170
196
  {
171
197
  type: 'text',
172
198
  name: 'projectKeywords',
173
199
  message: 'Keywords (comma separated)',
174
200
  initial: (projectKeywords.length > 0) ? projectKeywords.join(', ') : '',
175
- validate: (value) => CliUtilityInitialize.normalizeTextArray(value, 50)['result'],
201
+ validate: validateProjectKeywords,
176
202
  },
177
203
  ]);
178
204
  if (questionsOutput['cancelled'] === true) {
179
205
  return 'back';
180
206
  }
181
- const questionsOutputResult = questionsOutput['result'];
182
- const projectNameTitleInput = CliUtilityInitialize.normalizeText(questionsOutputResult.projectNameTitle, Infinity)['sanitized'];
183
- const projectNameSlugInput = CliUtilityInitialize.normalizeProjectSlug(questionsOutputResult.projectNameSlug)['sanitized'];
184
- const projectDescriptionShortInput = CliUtilityInitialize.normalizeText(questionsOutputResult.projectDescriptionShort, Infinity)['sanitized'];
185
- const projectDescriptionLongInput = CliUtilityInitialize.normalizeText(questionsOutputResult.projectDescriptionLong, Infinity)['sanitized'];
186
- const projectKeywordsInput = CliUtilityInitialize.normalizeTextArray(questionsOutputResult.projectKeywords, 50)['sanitized'];
207
+ const questionsOutputResultValue = questionsOutput['result'];
208
+ const projectNameTitleInput = Runner.normalizeText(questionsOutputResultValue.projectNameTitle, Infinity)['sanitized'];
209
+ const projectNameSlugInput = Runner.normalizeProjectSlug(questionsOutputResultValue.projectNameSlug)['sanitized'];
210
+ const projectDescriptionShortInput = Runner.normalizeText(questionsOutputResultValue.projectDescriptionShort, Infinity)['sanitized'];
211
+ const projectDescriptionLongInput = Runner.normalizeText(questionsOutputResultValue.projectDescriptionLong, Infinity)['sanitized'];
212
+ const projectKeywordsInput = Runner.normalizeTextArray(questionsOutputResultValue.projectKeywords, 50)['sanitized'];
187
213
  if (projectNameTitleInput !== undefined) {
188
214
  projectName.title = projectNameTitleInput;
189
215
  }
@@ -226,7 +252,7 @@ export class CliUtilityInitialize {
226
252
  else {
227
253
  Reflect.deleteProperty(project, 'keywords');
228
254
  }
229
- const legalNameOutput = await CliUtilityInitialize.promptWithCancel({
255
+ const legalNameOutput = await Runner.promptWithCancel({
230
256
  type: 'text',
231
257
  name: 'projectLegalName',
232
258
  message: 'Legal name (for licenses and copyright notices)',
@@ -235,14 +261,14 @@ export class CliUtilityInitialize {
235
261
  if (legalNameOutput['cancelled'] === true) {
236
262
  return 'back';
237
263
  }
238
- const projectLegalNameInput = CliUtilityInitialize.normalizeText(legalNameOutput['result'].projectLegalName, Infinity)['sanitized'];
264
+ const projectLegalNameInput = Runner.normalizeText(legalNameOutput['result'].projectLegalName, Infinity)['sanitized'];
239
265
  if (projectLegalNameInput !== undefined) {
240
266
  project.legalName = projectLegalNameInput;
241
267
  }
242
268
  else {
243
269
  Reflect.deleteProperty(project, 'legalName');
244
270
  }
245
- const pronounsOutput = await CliUtilityInitialize.promptWithCancel({
271
+ const pronounsOutput = await Runner.promptWithCancel({
246
272
  type: 'select',
247
273
  name: 'projectPronouns',
248
274
  message: 'Pronouns',
@@ -325,7 +351,7 @@ export class CliUtilityInitialize {
325
351
  selected: existingProjectPlatforms !== undefined && existingProjectPlatforms.includes('windows') === true,
326
352
  },
327
353
  ];
328
- const platformsOutput = await CliUtilityInitialize.promptWithCancel({
354
+ const platformsOutput = await Runner.promptWithCancel({
329
355
  type: 'multiselect',
330
356
  name: 'projectPlatforms',
331
357
  message: 'Supported platforms',
@@ -341,24 +367,25 @@ export class CliUtilityInitialize {
341
367
  else {
342
368
  Reflect.deleteProperty(project, 'platforms');
343
369
  }
344
- const startingYearOutput = await CliUtilityInitialize.promptWithCancel({
370
+ const validateProjectStartingYear = (projectStartingYearValue) => {
371
+ const trimmed = String(projectStartingYearValue ?? '').trim();
372
+ if (trimmed === '') {
373
+ return true;
374
+ }
375
+ const parsed = Number(trimmed);
376
+ if (Number.isNaN(parsed) === true
377
+ || Number.isInteger(parsed) === false
378
+ || parsed < 1970) {
379
+ return 'Must be an integer >= 1970';
380
+ }
381
+ return true;
382
+ };
383
+ const startingYearOutput = await Runner.promptWithCancel({
345
384
  type: 'text',
346
385
  name: 'projectStartingYear',
347
386
  message: 'Starting year (e.g. 2025)',
348
387
  initial: (existingProjectStartingYear !== undefined) ? String(existingProjectStartingYear) : '',
349
- validate: (value) => {
350
- const trimmed = String(value ?? '').trim();
351
- if (trimmed === '') {
352
- return true;
353
- }
354
- const parsed = Number(trimmed);
355
- if (Number.isNaN(parsed) === true
356
- || Number.isInteger(parsed) === false
357
- || parsed < 1970) {
358
- return 'Must be an integer >= 1970';
359
- }
360
- return true;
361
- },
388
+ validate: validateProjectStartingYear,
362
389
  });
363
390
  if (startingYearOutput['cancelled'] === true) {
364
391
  return 'back';
@@ -432,7 +459,7 @@ export class CliUtilityInitialize {
432
459
  },
433
460
  ];
434
461
  const licenseInitialIndex = licenseChoices.findIndex((choice) => choice['value'] === existingProjectLicense);
435
- const licenseOutput = await CliUtilityInitialize.promptWithCancel({
462
+ const licenseOutput = await Runner.promptWithCancel({
436
463
  type: 'select',
437
464
  name: 'projectLicense',
438
465
  message: 'License',
@@ -464,7 +491,7 @@ export class CliUtilityInitialize {
464
491
  const previousLabel = (previousSlug !== '') ? previousSlug : '(unset)';
465
492
  const currentLabel = (currentSlug !== '') ? currentSlug : '(unset)';
466
493
  Logger.customize({
467
- name: 'CliUtilityInitialize.promptProject',
494
+ name: 'Runner.promptProject',
468
495
  purpose: 'updated',
469
496
  padTop: 1,
470
497
  }).info(`Project slug updated from "${previousLabel}" to "${currentLabel}".`);
@@ -483,13 +510,13 @@ export class CliUtilityInitialize {
483
510
  workspace.name = name.replace(slugPrefix, `${currentSlug}-`);
484
511
  }
485
512
  Logger.customize({
486
- name: 'CliUtilityInitialize.promptProject',
513
+ name: 'Runner.promptProject',
487
514
  purpose: 'updated',
488
515
  }).info(`Workspace name updated from "${name}" to "${workspace['name']}".`);
489
516
  }
490
517
  }
491
518
  Logger.customize({
492
- name: 'CliUtilityInitialize.promptProject',
519
+ name: 'Runner.promptProject',
493
520
  purpose: 'updated',
494
521
  padTop: (slugChanged === true && config['workspaces'] !== undefined) ? 0 : 1,
495
522
  padBottom: 1,
@@ -602,7 +629,7 @@ export class CliUtilityInitialize {
602
629
  kind: 'back',
603
630
  },
604
631
  });
605
- const menuOutput = await CliUtilityInitialize.promptWithCancel({
632
+ const menuOutput = await Runner.promptWithCancel({
606
633
  type: 'select',
607
634
  name: 'action',
608
635
  message: (entities.length > 0) ? 'Select an entity to manage.' : 'No entities found. Choose an option.',
@@ -611,73 +638,73 @@ export class CliUtilityInitialize {
611
638
  if (menuOutput['cancelled'] === true) {
612
639
  return 'back';
613
640
  }
614
- const menuOutputResult = menuOutput['result'];
615
- if (menuOutputResult.action === undefined
616
- || menuOutputResult.action['kind'] === 'back') {
641
+ const menuOutputResultValue = menuOutput['result'];
642
+ if (menuOutputResultValue.action === undefined
643
+ || menuOutputResultValue.action['kind'] === 'back') {
617
644
  sync();
618
645
  return 'back';
619
646
  }
620
- if (menuOutputResult.action['kind'] === 'add') {
621
- const result = await CliUtilityInitialize.promptEntitiesForm(undefined, 'create');
647
+ if (menuOutputResultValue.action['kind'] === 'add') {
648
+ const result = await Runner.promptEntitiesForm(undefined, 'create');
622
649
  if (result['action'] === 'back') {
623
650
  continue;
624
651
  }
625
652
  entities.push(result['entity']);
626
653
  sync();
627
654
  Logger.customize({
628
- name: 'CliUtilityInitialize.promptEntities',
655
+ name: 'Runner.promptEntities',
629
656
  purpose: 'add',
630
657
  padTop: 1,
631
658
  padBottom: 1,
632
659
  }).info('Added new entity.');
633
660
  continue;
634
661
  }
635
- if (menuOutputResult.action['kind'] === 'edit') {
636
- const entityIndex = menuOutputResult.action['index'];
662
+ if (menuOutputResultValue.action['kind'] === 'edit') {
663
+ const entityIndex = menuOutputResultValue.action['index'];
637
664
  if (entityIndex < 0 || entityIndex >= entities.length) {
638
665
  continue;
639
666
  }
640
667
  const entityToEdit = entities[entityIndex];
641
- const entityResult = await CliUtilityInitialize.promptEntitiesForm(entityToEdit, 'update');
668
+ const entityResult = await Runner.promptEntitiesForm(entityToEdit, 'update');
642
669
  if (entityResult['action'] === 'back') {
643
670
  continue;
644
671
  }
645
672
  Reflect.set(entities, entityIndex, entityResult['entity']);
646
673
  sync();
647
674
  Logger.customize({
648
- name: 'CliUtilityInitialize.promptEntities',
675
+ name: 'Runner.promptEntities',
649
676
  purpose: 'edit',
650
677
  padTop: 1,
651
678
  padBottom: 1,
652
679
  }).info('Updated entity.');
653
680
  continue;
654
681
  }
655
- if (menuOutputResult.action['kind'] === 'remove') {
656
- const entityIndex = menuOutputResult.action['index'];
657
- if (entityIndex < 0 || entityIndex >= entities.length) {
682
+ if (menuOutputResultValue.action['kind'] === 'remove') {
683
+ const removeEntityIndex = menuOutputResultValue.action['index'];
684
+ if (removeEntityIndex < 0 || removeEntityIndex >= entities.length) {
658
685
  continue;
659
686
  }
660
- const entityToRemove = entities[entityIndex];
687
+ const entityToRemove = entities[removeEntityIndex];
661
688
  if (entityToRemove === undefined) {
662
689
  continue;
663
690
  }
664
- const entityName = (typeof entityToRemove['name'] === 'string') ? entityToRemove['name'].trim() : '';
665
- const entityEmail = (typeof entityToRemove['email'] === 'string') ? entityToRemove['email'].trim() : '';
666
- let entityLabel = `Entity ${entityIndex + 1}`;
667
- if (entityName !== '') {
668
- entityLabel = entityName;
691
+ const removeEntityName = (typeof entityToRemove['name'] === 'string') ? entityToRemove['name'].trim() : '';
692
+ const removeEntityEmail = (typeof entityToRemove['email'] === 'string') ? entityToRemove['email'].trim() : '';
693
+ let entityLabel = `Entity ${removeEntityIndex + 1}`;
694
+ if (removeEntityName !== '') {
695
+ entityLabel = removeEntityName;
669
696
  }
670
- else if (entityEmail !== '') {
671
- entityLabel = entityEmail;
697
+ else if (removeEntityEmail !== '') {
698
+ entityLabel = removeEntityEmail;
672
699
  }
673
- const shouldRemove = await CliUtilityInitialize.promptEntitiesDeleteForm(entityLabel);
700
+ const shouldRemove = await Runner.promptEntitiesDeleteForm(entityLabel);
674
701
  if (shouldRemove !== true) {
675
702
  continue;
676
703
  }
677
- entities.splice(entityIndex, 1);
704
+ entities.splice(removeEntityIndex, 1);
678
705
  sync();
679
706
  Logger.customize({
680
- name: 'CliUtilityInitialize.promptEntities',
707
+ name: 'Runner.promptEntities',
681
708
  purpose: 'remove',
682
709
  padTop: 1,
683
710
  padBottom: 1,
@@ -694,27 +721,36 @@ export class CliUtilityInitialize {
694
721
  if (entity !== undefined && Array.isArray(entity['roles']) === true) {
695
722
  existingRoles = entity['roles'].filter((role) => validRoles.includes(role));
696
723
  }
697
- const questionsOutput = await CliUtilityInitialize.promptWithCancel([
724
+ const validateEntityName = (entityNameValue) => {
725
+ return Runner.normalizeText(entityNameValue, Infinity)['result'];
726
+ };
727
+ const validateEntityEmail = (entityEmailValue) => {
728
+ return Runner.normalizeEmail(entityEmailValue)['result'];
729
+ };
730
+ const validateEntityUrl = (entityUrlValue) => {
731
+ return Runner.normalizeUrl(entityUrlValue, 'generic')['result'];
732
+ };
733
+ const questionsOutput = await Runner.promptWithCancel([
698
734
  {
699
735
  type: 'text',
700
736
  name: 'entityName',
701
737
  message: 'Entity name',
702
738
  initial: existingName,
703
- validate: (value) => CliUtilityInitialize.normalizeText(value, Infinity)['result'],
739
+ validate: validateEntityName,
704
740
  },
705
741
  {
706
742
  type: 'text',
707
743
  name: 'entityEmail',
708
744
  message: 'Entity email address',
709
745
  initial: existingEmail,
710
- validate: (value) => CliUtilityInitialize.normalizeEmail(value)['result'],
746
+ validate: validateEntityEmail,
711
747
  },
712
748
  {
713
749
  type: 'text',
714
750
  name: 'entityUrl',
715
751
  message: 'Entity website',
716
752
  initial: existingUrl,
717
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
753
+ validate: validateEntityUrl,
718
754
  },
719
755
  {
720
756
  type: 'multiselect',
@@ -733,9 +769,9 @@ export class CliUtilityInitialize {
733
769
  };
734
770
  }
735
771
  const questionsOutputResult = questionsOutput['result'];
736
- const entityNameInput = CliUtilityInitialize.normalizeText(questionsOutputResult.entityName, Infinity)['sanitized'];
737
- const entityEmailInput = CliUtilityInitialize.normalizeEmail(questionsOutputResult.entityEmail)['sanitized'];
738
- const entityUrlInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.entityUrl, 'generic')['sanitized'];
772
+ const entityNameInput = Runner.normalizeText(questionsOutputResult.entityName, Infinity)['sanitized'];
773
+ const entityEmailInput = Runner.normalizeEmail(questionsOutputResult.entityEmail)['sanitized'];
774
+ const entityUrlInput = Runner.normalizeUrl(questionsOutputResult.entityUrl, 'generic')['sanitized'];
739
775
  const entityRolesInput = (Array.isArray(questionsOutputResult.entityRoles) === true) ? [...questionsOutputResult.entityRoles] : [];
740
776
  const resolvedEntity = {};
741
777
  if (entityNameInput !== undefined) {
@@ -761,7 +797,7 @@ export class CliUtilityInitialize {
761
797
  };
762
798
  }
763
799
  static async promptEntitiesDeleteForm(label) {
764
- const confirmOutput = await CliUtilityInitialize.promptWithCancel({
800
+ const confirmOutput = await Runner.promptWithCancel({
765
801
  type: 'confirm',
766
802
  name: 'confirm',
767
803
  message: `Remove entity "${label}"?`,
@@ -776,18 +812,21 @@ export class CliUtilityInitialize {
776
812
  static async promptEmails(config) {
777
813
  const existingEmails = config['emails'];
778
814
  const emails = (existingEmails !== undefined) ? { ...existingEmails } : {};
779
- const questionsOutput = await CliUtilityInitialize.promptWithCancel([{
815
+ const validateEmailsBugs = (emailsBugsValue) => {
816
+ return Runner.normalizeEmail(emailsBugsValue)['result'];
817
+ };
818
+ const questionsOutput = await Runner.promptWithCancel([{
780
819
  type: 'text',
781
820
  name: 'emailsBugs',
782
821
  message: 'Issue tracker email',
783
822
  initial: emails['bugs'] ?? '',
784
- validate: (value) => CliUtilityInitialize.normalizeEmail(value)['result'],
823
+ validate: validateEmailsBugs,
785
824
  }]);
786
825
  if (questionsOutput['cancelled'] === true) {
787
826
  return 'back';
788
827
  }
789
828
  const questionsOutputResult = questionsOutput['result'];
790
- const emailsBugsInput = CliUtilityInitialize.normalizeEmail(questionsOutputResult.emailsBugs)['sanitized'];
829
+ const emailsBugsInput = Runner.normalizeEmail(questionsOutputResult.emailsBugs)['sanitized'];
791
830
  if (emailsBugsInput !== undefined) {
792
831
  emails.bugs = emailsBugsInput;
793
832
  }
@@ -801,118 +840,610 @@ export class CliUtilityInitialize {
801
840
  Reflect.deleteProperty(config, 'emails');
802
841
  }
803
842
  Logger.customize({
804
- name: 'CliUtilityInitialize.promptEmails',
843
+ name: 'Runner.promptEmails',
805
844
  purpose: 'updated',
806
845
  padTop: 1,
807
846
  padBottom: 1,
808
847
  }).info('Email references updated.');
809
848
  return 'back';
810
849
  }
850
+ static async promptGithub(config) {
851
+ const existingGithub = config['github'];
852
+ const github = (existingGithub !== undefined) ? { ...existingGithub } : {};
853
+ const validateGithubOwner = (githubOwnerValue) => {
854
+ const trimmed = (typeof githubOwnerValue === 'string') ? githubOwnerValue.trim() : '';
855
+ if (trimmed === '') {
856
+ return 'Owner is required.';
857
+ }
858
+ return true;
859
+ };
860
+ const ownerOutput = await Runner.promptWithCancel({
861
+ type: 'text',
862
+ name: 'githubOwner',
863
+ message: 'GitHub owner (organization or user)',
864
+ initial: (github['owner'] !== undefined) ? github['owner'] : '',
865
+ validate: validateGithubOwner,
866
+ });
867
+ if (ownerOutput['cancelled'] === true) {
868
+ return 'back';
869
+ }
870
+ const ownerOutputResult = ownerOutput['result'];
871
+ const githubOwnerInput = ownerOutputResult.githubOwner.trim();
872
+ const validateGithubRepo = (githubRepoValue) => {
873
+ const trimmed = (typeof githubRepoValue === 'string') ? githubRepoValue.trim() : '';
874
+ if (trimmed === '') {
875
+ return 'Repository name is required.';
876
+ }
877
+ return true;
878
+ };
879
+ const repoOutput = await Runner.promptWithCancel({
880
+ type: 'text',
881
+ name: 'githubRepo',
882
+ message: 'GitHub repository name',
883
+ initial: (github['repo'] !== undefined) ? github['repo'] : '',
884
+ validate: validateGithubRepo,
885
+ });
886
+ if (repoOutput['cancelled'] === true) {
887
+ return 'back';
888
+ }
889
+ const repoOutputResult = repoOutput['result'];
890
+ const githubRepoInput = repoOutputResult.githubRepo.trim();
891
+ const existingRecipes = github['recipes'];
892
+ const syncIdentityInitial = (existingRecipes !== undefined && existingRecipes['sync-identity'] !== undefined) ? existingRecipes['sync-identity'] : true;
893
+ const syncFeaturesInitial = (existingRecipes !== undefined && existingRecipes['sync-features'] !== undefined) ? existingRecipes['sync-features'] : false;
894
+ const syncPoliciesInitial = (existingRecipes !== undefined && existingRecipes['sync-policies'] !== undefined) ? existingRecipes['sync-policies'] : false;
895
+ const recipesOutput = await Runner.promptWithCancel([
896
+ {
897
+ type: 'confirm',
898
+ name: 'githubRecipeSyncIdentity',
899
+ message: 'Enable sync-identity recipe?',
900
+ initial: syncIdentityInitial,
901
+ },
902
+ {
903
+ type: 'confirm',
904
+ name: 'githubRecipeSyncFeatures',
905
+ message: 'Enable sync-features recipe?',
906
+ initial: syncFeaturesInitial,
907
+ },
908
+ {
909
+ type: 'confirm',
910
+ name: 'githubRecipeSyncPolicies',
911
+ message: 'Enable sync-policies recipe?',
912
+ initial: syncPoliciesInitial,
913
+ },
914
+ ]);
915
+ if (recipesOutput['cancelled'] === true) {
916
+ return 'back';
917
+ }
918
+ const recipesOutputResult = recipesOutput['result'];
919
+ const githubRecipesInput = {
920
+ 'sync-identity': recipesOutputResult.githubRecipeSyncIdentity,
921
+ 'sync-features': recipesOutputResult.githubRecipeSyncFeatures,
922
+ 'sync-policies': recipesOutputResult.githubRecipeSyncPolicies,
923
+ };
924
+ const existingTopics = github['topics'];
925
+ const topicsHasExisting = (existingTopics !== undefined) && existingTopics.length > 0;
926
+ const topicsTitle = (existingTopics !== undefined && topicsHasExisting === true) ? `Keep existing: ${existingTopics.join(', ')}` : 'Enter topics (comma-separated)';
927
+ const topicsValue = (existingTopics !== undefined) ? existingTopics : [];
928
+ const topicsInitial = (existingTopics !== undefined) ? 1 : 0;
929
+ const topicsOutput = await Runner.promptWithCancel({
930
+ type: 'select',
931
+ name: 'githubTopics',
932
+ message: 'GitHub topics (sync this field?)',
933
+ choices: [
934
+ {
935
+ title: 'Skip (don\'t sync this field)',
936
+ value: 'skip',
937
+ },
938
+ {
939
+ title: topicsTitle,
940
+ value: topicsValue,
941
+ },
942
+ ],
943
+ initial: topicsInitial,
944
+ });
945
+ if (topicsOutput['cancelled'] === true) {
946
+ return 'back';
947
+ }
948
+ const topicsOutputResult = topicsOutput['result'];
949
+ let githubTopicsInput = undefined;
950
+ if (topicsOutputResult.githubTopics !== 'skip') {
951
+ if (existingTopics !== undefined && existingTopics.length > 0) {
952
+ githubTopicsInput = existingTopics;
953
+ }
954
+ else {
955
+ const topicsTextOutput = await Runner.promptWithCancel({
956
+ type: 'text',
957
+ name: 'githubOwner',
958
+ message: 'Topics (comma-separated)',
959
+ initial: '',
960
+ });
961
+ if (topicsTextOutput['cancelled'] === true) {
962
+ return 'back';
963
+ }
964
+ const rawTopics = topicsTextOutput['result'].githubOwner;
965
+ const parsedTopics = rawTopics.split(',').map((t) => t.trim()).filter((t) => t !== '');
966
+ if (parsedTopics.length > 0) {
967
+ githubTopicsInput = parsedTopics;
968
+ }
969
+ }
970
+ }
971
+ const existingFeatures = github['features'];
972
+ let featuresIssuesInitial = 0;
973
+ if (existingFeatures !== undefined && existingFeatures['issues'] !== undefined) {
974
+ featuresIssuesInitial = (existingFeatures['issues'] === true) ? 1 : 2;
975
+ }
976
+ let featuresWikiInitial = 0;
977
+ if (existingFeatures !== undefined && existingFeatures['wiki'] !== undefined) {
978
+ featuresWikiInitial = (existingFeatures['wiki'] === true) ? 1 : 2;
979
+ }
980
+ let featuresProjectsInitial = 0;
981
+ if (existingFeatures !== undefined && existingFeatures['projects'] !== undefined) {
982
+ featuresProjectsInitial = (existingFeatures['projects'] === true) ? 1 : 2;
983
+ }
984
+ let featuresDiscussionsInitial = 0;
985
+ if (existingFeatures !== undefined && existingFeatures['discussions'] !== undefined) {
986
+ featuresDiscussionsInitial = (existingFeatures['discussions'] === true) ? 1 : 2;
987
+ }
988
+ const featuresOutput = await Runner.promptWithCancel([
989
+ {
990
+ type: 'select',
991
+ name: 'githubFeaturesIssues',
992
+ message: 'GitHub features.issues (sync this field?)',
993
+ choices: [
994
+ {
995
+ title: 'Skip (don\'t sync this field)',
996
+ value: 'skip',
997
+ },
998
+ {
999
+ title: 'Enable',
1000
+ value: true,
1001
+ },
1002
+ {
1003
+ title: 'Disable',
1004
+ value: false,
1005
+ },
1006
+ ],
1007
+ initial: featuresIssuesInitial,
1008
+ },
1009
+ {
1010
+ type: 'select',
1011
+ name: 'githubFeaturesWiki',
1012
+ message: 'GitHub features.wiki (sync this field?)',
1013
+ choices: [
1014
+ {
1015
+ title: 'Skip (don\'t sync this field)',
1016
+ value: 'skip',
1017
+ },
1018
+ {
1019
+ title: 'Enable',
1020
+ value: true,
1021
+ },
1022
+ {
1023
+ title: 'Disable',
1024
+ value: false,
1025
+ },
1026
+ ],
1027
+ initial: featuresWikiInitial,
1028
+ },
1029
+ {
1030
+ type: 'select',
1031
+ name: 'githubFeaturesProjects',
1032
+ message: 'GitHub features.projects (sync this field?)',
1033
+ choices: [
1034
+ {
1035
+ title: 'Skip (don\'t sync this field)',
1036
+ value: 'skip',
1037
+ },
1038
+ {
1039
+ title: 'Enable',
1040
+ value: true,
1041
+ },
1042
+ {
1043
+ title: 'Disable',
1044
+ value: false,
1045
+ },
1046
+ ],
1047
+ initial: featuresProjectsInitial,
1048
+ },
1049
+ {
1050
+ type: 'select',
1051
+ name: 'githubFeaturesDiscussions',
1052
+ message: 'GitHub features.discussions (sync this field?)',
1053
+ choices: [
1054
+ {
1055
+ title: 'Skip (don\'t sync this field)',
1056
+ value: 'skip',
1057
+ },
1058
+ {
1059
+ title: 'Enable',
1060
+ value: true,
1061
+ },
1062
+ {
1063
+ title: 'Disable',
1064
+ value: false,
1065
+ },
1066
+ ],
1067
+ initial: featuresDiscussionsInitial,
1068
+ },
1069
+ ]);
1070
+ if (featuresOutput['cancelled'] === true) {
1071
+ return 'back';
1072
+ }
1073
+ const featuresOutputResult = featuresOutput['result'];
1074
+ let githubFeaturesInput = undefined;
1075
+ const featuresIssuesValue = featuresOutputResult.githubFeaturesIssues;
1076
+ const featuresWikiValue = featuresOutputResult.githubFeaturesWiki;
1077
+ const featuresProjectsValue = featuresOutputResult.githubFeaturesProjects;
1078
+ const featuresDiscussionsValue = featuresOutputResult.githubFeaturesDiscussions;
1079
+ if (featuresIssuesValue !== 'skip'
1080
+ || featuresWikiValue !== 'skip'
1081
+ || featuresProjectsValue !== 'skip'
1082
+ || featuresDiscussionsValue !== 'skip') {
1083
+ githubFeaturesInput = {
1084
+ ...((featuresIssuesValue !== 'skip') ? { issues: featuresIssuesValue } : {}),
1085
+ ...((featuresWikiValue !== 'skip') ? { wiki: featuresWikiValue } : {}),
1086
+ ...((featuresProjectsValue !== 'skip') ? { projects: featuresProjectsValue } : {}),
1087
+ ...((featuresDiscussionsValue !== 'skip') ? { discussions: featuresDiscussionsValue } : {}),
1088
+ };
1089
+ }
1090
+ const existingPolicies = github['policies'];
1091
+ const existingVisibility = (existingPolicies !== undefined) ? existingPolicies['visibility'] : undefined;
1092
+ const visibilityOrder = [
1093
+ 'public',
1094
+ 'private',
1095
+ 'internal',
1096
+ ];
1097
+ const visibilityInitial = (existingVisibility !== undefined) ? (visibilityOrder.indexOf(existingVisibility) + 1) : 0;
1098
+ const visibilityOutput = await Runner.promptWithCancel({
1099
+ type: 'select',
1100
+ name: 'githubPoliciesVisibility',
1101
+ message: 'GitHub policies.visibility (sync this field?)',
1102
+ choices: [
1103
+ {
1104
+ title: 'Skip (don\'t sync this field)',
1105
+ value: 'skip',
1106
+ },
1107
+ {
1108
+ title: 'Public',
1109
+ value: 'public',
1110
+ },
1111
+ {
1112
+ title: 'Private',
1113
+ value: 'private',
1114
+ },
1115
+ {
1116
+ title: 'Internal',
1117
+ value: 'internal',
1118
+ },
1119
+ ],
1120
+ initial: visibilityInitial,
1121
+ });
1122
+ if (visibilityOutput['cancelled'] === true) {
1123
+ return 'back';
1124
+ }
1125
+ const visibilityOutputResult = visibilityOutput['result'];
1126
+ const githubPoliciesVisibilityValue = visibilityOutputResult.githubPoliciesVisibility;
1127
+ const existingDefaultBranch = (existingPolicies !== undefined) ? existingPolicies['defaultBranch'] : undefined;
1128
+ const defaultBranchTitle = (existingDefaultBranch !== undefined) ? `Keep existing: ${existingDefaultBranch}` : 'Enter default branch name';
1129
+ const defaultBranchChoiceValue = (existingDefaultBranch !== undefined) ? existingDefaultBranch : 'enter';
1130
+ const defaultBranchInitial = (existingDefaultBranch !== undefined) ? 1 : 0;
1131
+ const defaultBranchOutput = await Runner.promptWithCancel({
1132
+ type: 'select',
1133
+ name: 'githubPoliciesDefaultBranch',
1134
+ message: 'GitHub policies.defaultBranch (sync this field?)',
1135
+ choices: [
1136
+ {
1137
+ title: 'Skip (don\'t sync this field)',
1138
+ value: 'skip',
1139
+ },
1140
+ {
1141
+ title: defaultBranchTitle,
1142
+ value: defaultBranchChoiceValue,
1143
+ },
1144
+ ],
1145
+ initial: defaultBranchInitial,
1146
+ });
1147
+ if (defaultBranchOutput['cancelled'] === true) {
1148
+ return 'back';
1149
+ }
1150
+ const defaultBranchOutputResult = defaultBranchOutput['result'];
1151
+ let githubPoliciesDefaultBranchValue = defaultBranchOutputResult.githubPoliciesDefaultBranch;
1152
+ if (githubPoliciesDefaultBranchValue === 'enter') {
1153
+ const defaultBranchTextOutput = await Runner.promptWithCancel({
1154
+ type: 'text',
1155
+ name: 'githubRepo',
1156
+ message: 'Default branch name',
1157
+ initial: '',
1158
+ });
1159
+ if (defaultBranchTextOutput['cancelled'] === true) {
1160
+ return 'back';
1161
+ }
1162
+ const rawDefaultBranch = defaultBranchTextOutput['result'].githubRepo.trim();
1163
+ githubPoliciesDefaultBranchValue = (rawDefaultBranch !== '') ? rawDefaultBranch : 'skip';
1164
+ }
1165
+ const existingMergeMethods = github['policies'];
1166
+ const existingMergeMethodsObj = (existingMergeMethods !== undefined) ? existingMergeMethods['mergeMethods'] : undefined;
1167
+ let mergeInitial = 0;
1168
+ if (existingMergeMethodsObj !== undefined && existingMergeMethodsObj['merge'] !== undefined) {
1169
+ mergeInitial = (existingMergeMethodsObj['merge'] === true) ? 1 : 2;
1170
+ }
1171
+ let squashInitial = 0;
1172
+ if (existingMergeMethodsObj !== undefined && existingMergeMethodsObj['squash'] !== undefined) {
1173
+ squashInitial = (existingMergeMethodsObj['squash'] === true) ? 1 : 2;
1174
+ }
1175
+ let rebaseInitial = 0;
1176
+ if (existingMergeMethodsObj !== undefined && existingMergeMethodsObj['rebase'] !== undefined) {
1177
+ rebaseInitial = (existingMergeMethodsObj['rebase'] === true) ? 1 : 2;
1178
+ }
1179
+ const mergeMethodsOutput = await Runner.promptWithCancel([
1180
+ {
1181
+ type: 'select',
1182
+ name: 'githubPoliciesMergeMethodsMerge',
1183
+ message: 'GitHub policies.mergeMethods.merge (sync this field?)',
1184
+ choices: [
1185
+ {
1186
+ title: 'Skip (don\'t sync this field)',
1187
+ value: 'skip',
1188
+ },
1189
+ {
1190
+ title: 'Enable',
1191
+ value: true,
1192
+ },
1193
+ {
1194
+ title: 'Disable',
1195
+ value: false,
1196
+ },
1197
+ ],
1198
+ initial: mergeInitial,
1199
+ },
1200
+ {
1201
+ type: 'select',
1202
+ name: 'githubPoliciesMergeMethodsSquash',
1203
+ message: 'GitHub policies.mergeMethods.squash (sync this field?)',
1204
+ choices: [
1205
+ {
1206
+ title: 'Skip (don\'t sync this field)',
1207
+ value: 'skip',
1208
+ },
1209
+ {
1210
+ title: 'Enable',
1211
+ value: true,
1212
+ },
1213
+ {
1214
+ title: 'Disable',
1215
+ value: false,
1216
+ },
1217
+ ],
1218
+ initial: squashInitial,
1219
+ },
1220
+ {
1221
+ type: 'select',
1222
+ name: 'githubPoliciesMergeMethodsRebase',
1223
+ message: 'GitHub policies.mergeMethods.rebase (sync this field?)',
1224
+ choices: [
1225
+ {
1226
+ title: 'Skip (don\'t sync this field)',
1227
+ value: 'skip',
1228
+ },
1229
+ {
1230
+ title: 'Enable',
1231
+ value: true,
1232
+ },
1233
+ {
1234
+ title: 'Disable',
1235
+ value: false,
1236
+ },
1237
+ ],
1238
+ initial: rebaseInitial,
1239
+ },
1240
+ ]);
1241
+ if (mergeMethodsOutput['cancelled'] === true) {
1242
+ return 'back';
1243
+ }
1244
+ const mergeMethodsOutputResult = mergeMethodsOutput['result'];
1245
+ let githubPoliciesMergeMethodsInput = undefined;
1246
+ const mergeMethodsMergeValue = mergeMethodsOutputResult.githubPoliciesMergeMethodsMerge;
1247
+ const mergeMethodsSquashValue = mergeMethodsOutputResult.githubPoliciesMergeMethodsSquash;
1248
+ const mergeMethodsRebaseValue = mergeMethodsOutputResult.githubPoliciesMergeMethodsRebase;
1249
+ if (mergeMethodsMergeValue !== 'skip'
1250
+ || mergeMethodsSquashValue !== 'skip'
1251
+ || mergeMethodsRebaseValue !== 'skip') {
1252
+ githubPoliciesMergeMethodsInput = {
1253
+ ...((mergeMethodsMergeValue !== 'skip') ? { merge: mergeMethodsMergeValue } : {}),
1254
+ ...((mergeMethodsSquashValue !== 'skip') ? { squash: mergeMethodsSquashValue } : {}),
1255
+ ...((mergeMethodsRebaseValue !== 'skip') ? { rebase: mergeMethodsRebaseValue } : {}),
1256
+ };
1257
+ }
1258
+ const existingAutoDelete = (existingPolicies !== undefined) ? existingPolicies['autoDeleteHeadBranch'] : undefined;
1259
+ let autoDeleteInitial = 0;
1260
+ if (existingAutoDelete !== undefined) {
1261
+ autoDeleteInitial = (existingAutoDelete === true) ? 1 : 2;
1262
+ }
1263
+ const autoDeleteOutput = await Runner.promptWithCancel({
1264
+ type: 'select',
1265
+ name: 'githubPoliciesAutoDeleteHeadBranch',
1266
+ message: 'GitHub policies.autoDeleteHeadBranch (sync this field?)',
1267
+ choices: [
1268
+ {
1269
+ title: 'Skip (don\'t sync this field)',
1270
+ value: 'skip',
1271
+ },
1272
+ {
1273
+ title: 'Enable',
1274
+ value: true,
1275
+ },
1276
+ {
1277
+ title: 'Disable',
1278
+ value: false,
1279
+ },
1280
+ ],
1281
+ initial: autoDeleteInitial,
1282
+ });
1283
+ if (autoDeleteOutput['cancelled'] === true) {
1284
+ return 'back';
1285
+ }
1286
+ const autoDeleteOutputResult = autoDeleteOutput['result'];
1287
+ const githubPoliciesAutoDeleteValue = autoDeleteOutputResult.githubPoliciesAutoDeleteHeadBranch;
1288
+ let githubPoliciesInput = undefined;
1289
+ if (githubPoliciesVisibilityValue !== 'skip'
1290
+ || githubPoliciesDefaultBranchValue !== 'skip'
1291
+ || githubPoliciesMergeMethodsInput !== undefined
1292
+ || githubPoliciesAutoDeleteValue !== 'skip') {
1293
+ githubPoliciesInput = {
1294
+ ...((githubPoliciesVisibilityValue !== 'skip') ? { visibility: githubPoliciesVisibilityValue } : {}),
1295
+ ...((githubPoliciesDefaultBranchValue !== 'skip') ? { defaultBranch: githubPoliciesDefaultBranchValue } : {}),
1296
+ ...(githubPoliciesMergeMethodsInput !== undefined ? { mergeMethods: githubPoliciesMergeMethodsInput } : {}),
1297
+ ...((githubPoliciesAutoDeleteValue !== 'skip') ? { autoDeleteHeadBranch: githubPoliciesAutoDeleteValue } : {}),
1298
+ };
1299
+ }
1300
+ const githubConfig = {
1301
+ owner: githubOwnerInput,
1302
+ repo: githubRepoInput,
1303
+ recipes: githubRecipesInput,
1304
+ ...(githubTopicsInput !== undefined ? { topics: githubTopicsInput } : {}),
1305
+ ...(githubFeaturesInput !== undefined ? { features: githubFeaturesInput } : {}),
1306
+ ...(githubPoliciesInput !== undefined ? { policies: githubPoliciesInput } : {}),
1307
+ };
1308
+ Object.assign(config, { github: githubConfig });
1309
+ Logger.customize({
1310
+ name: 'Runner.promptGithub',
1311
+ purpose: 'updated',
1312
+ padTop: 1,
1313
+ padBottom: 1,
1314
+ }).info('GitHub settings updated.');
1315
+ return 'back';
1316
+ }
811
1317
  static async promptUrls(config) {
812
1318
  const existingUrls = config['urls'];
813
1319
  const urls = (existingUrls !== undefined) ? { ...existingUrls } : {};
814
- const questionsOutput = await CliUtilityInitialize.promptWithCancel([
1320
+ const validateUrlsHomepage = (urlsHomepageValue) => {
1321
+ return Runner.normalizeUrl(urlsHomepageValue, 'generic')['result'];
1322
+ };
1323
+ const validateUrlsRepository = (urlsRepositoryValue) => {
1324
+ return Runner.normalizeUrl(urlsRepositoryValue, 'repository')['result'];
1325
+ };
1326
+ const validateUrlsBugs = (urlsBugsValue) => {
1327
+ return Runner.normalizeUrl(urlsBugsValue, 'generic')['result'];
1328
+ };
1329
+ const validateUrlsLicense = (urlsLicenseValue) => {
1330
+ return Runner.normalizeUrl(urlsLicenseValue, 'generic')['result'];
1331
+ };
1332
+ const validateUrlsLogo = (urlsLogoValue) => {
1333
+ return Runner.normalizeUrl(urlsLogoValue, 'generic')['result'];
1334
+ };
1335
+ const validateUrlsDocumentation = (urlsDocumentationValue) => {
1336
+ return Runner.normalizeUrl(urlsDocumentationValue, 'generic')['result'];
1337
+ };
1338
+ const validateUrlsNpm = (urlsNpmValue) => {
1339
+ return Runner.normalizeUrl(urlsNpmValue, 'generic')['result'];
1340
+ };
1341
+ const validateUrlsDocker = (urlsDockerValue) => {
1342
+ return Runner.normalizeUrl(urlsDockerValue, 'generic')['result'];
1343
+ };
1344
+ const validateUrlsFundSources = (urlsFundSourcesValue) => {
1345
+ return Runner.normalizeUrlArray(urlsFundSourcesValue, 'generic')['result'];
1346
+ };
1347
+ const validateUrlsPrivacyPolicy = (urlsPrivacyPolicyValue) => {
1348
+ return Runner.normalizeUrl(urlsPrivacyPolicyValue, 'generic')['result'];
1349
+ };
1350
+ const validateUrlsTermsOfUse = (urlsTermsOfUseValue) => {
1351
+ return Runner.normalizeUrl(urlsTermsOfUseValue, 'generic')['result'];
1352
+ };
1353
+ const questionsOutput = await Runner.promptWithCancel([
815
1354
  {
816
1355
  type: 'text',
817
1356
  name: 'urlsHomepage',
818
1357
  message: 'Homepage URL',
819
1358
  initial: urls['homepage'] ?? '',
820
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1359
+ validate: validateUrlsHomepage,
821
1360
  },
822
1361
  {
823
1362
  type: 'text',
824
1363
  name: 'urlsRepository',
825
1364
  message: 'Repository URL',
826
1365
  initial: urls['repository'] ?? '',
827
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'repository')['result'],
1366
+ validate: validateUrlsRepository,
828
1367
  },
829
1368
  {
830
1369
  type: 'text',
831
1370
  name: 'urlsBugs',
832
1371
  message: 'Issue tracker URL',
833
1372
  initial: urls['bugs'] ?? '',
834
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1373
+ validate: validateUrlsBugs,
835
1374
  },
836
1375
  {
837
1376
  type: 'text',
838
1377
  name: 'urlsLicense',
839
1378
  message: 'License URL',
840
1379
  initial: urls['license'] ?? '',
841
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1380
+ validate: validateUrlsLicense,
842
1381
  },
843
1382
  {
844
1383
  type: 'text',
845
1384
  name: 'urlsLogo',
846
1385
  message: 'Logo URL',
847
1386
  initial: urls['logo'] ?? '',
848
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1387
+ validate: validateUrlsLogo,
849
1388
  },
850
1389
  {
851
1390
  type: 'text',
852
1391
  name: 'urlsDocumentation',
853
1392
  message: 'Documentation URL',
854
1393
  initial: urls['documentation'] ?? '',
855
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
856
- },
857
- {
858
- type: 'text',
859
- name: 'urlsGithub',
860
- message: 'GitHub URL',
861
- initial: urls['github'] ?? '',
862
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1394
+ validate: validateUrlsDocumentation,
863
1395
  },
864
1396
  {
865
1397
  type: 'text',
866
1398
  name: 'urlsNpm',
867
1399
  message: 'npm package URL',
868
1400
  initial: urls['npm'] ?? '',
869
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1401
+ validate: validateUrlsNpm,
870
1402
  },
871
1403
  {
872
1404
  type: 'text',
873
1405
  name: 'urlsDocker',
874
1406
  message: 'Docker Hub URL',
875
1407
  initial: urls['docker'] ?? '',
876
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1408
+ validate: validateUrlsDocker,
877
1409
  },
878
1410
  {
879
1411
  type: 'text',
880
1412
  name: 'urlsFundSources',
881
1413
  message: 'Funding URLs (comma separated)',
882
1414
  initial: (Array.isArray(urls['fundSources']) === true) ? urls['fundSources'].join(', ') : '',
883
- validate: (value) => CliUtilityInitialize.normalizeUrlArray(value, 'generic')['result'],
1415
+ validate: validateUrlsFundSources,
884
1416
  },
885
1417
  {
886
1418
  type: 'text',
887
1419
  name: 'urlsPrivacyPolicy',
888
1420
  message: 'Privacy policy URL',
889
1421
  initial: urls['privacyPolicy'] ?? '',
890
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1422
+ validate: validateUrlsPrivacyPolicy,
891
1423
  },
892
1424
  {
893
1425
  type: 'text',
894
1426
  name: 'urlsTermsOfUse',
895
1427
  message: 'Terms of use URL',
896
1428
  initial: urls['termsOfUse'] ?? '',
897
- validate: (value) => CliUtilityInitialize.normalizeUrl(value, 'generic')['result'],
1429
+ validate: validateUrlsTermsOfUse,
898
1430
  },
899
1431
  ]);
900
1432
  if (questionsOutput['cancelled'] === true) {
901
1433
  return 'back';
902
1434
  }
903
1435
  const questionsOutputResult = questionsOutput['result'];
904
- const urlsHomepageInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsHomepage, 'generic')['sanitized'];
905
- const urlsRepositoryInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsRepository, 'repository')['sanitized'];
906
- const urlsBugsInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsBugs, 'generic')['sanitized'];
907
- const urlsLicenseInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsLicense, 'generic')['sanitized'];
908
- const urlsLogoInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsLogo, 'generic')['sanitized'];
909
- const urlsDocumentationInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsDocumentation, 'generic')['sanitized'];
910
- const urlsGithubInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsGithub, 'generic')['sanitized'];
911
- const urlsNpmInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsNpm, 'generic')['sanitized'];
912
- const urlsDockerInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsDocker, 'generic')['sanitized'];
913
- const urlsFundSourcesInput = CliUtilityInitialize.normalizeUrlArray(questionsOutputResult.urlsFundSources, 'generic')['sanitized'];
914
- const urlsPrivacyPolicyInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsPrivacyPolicy, 'generic')['sanitized'];
915
- const urlsTermsOfUseInput = CliUtilityInitialize.normalizeUrl(questionsOutputResult.urlsTermsOfUse, 'generic')['sanitized'];
1436
+ const urlsHomepageInput = Runner.normalizeUrl(questionsOutputResult.urlsHomepage, 'generic')['sanitized'];
1437
+ const urlsRepositoryInput = Runner.normalizeUrl(questionsOutputResult.urlsRepository, 'repository')['sanitized'];
1438
+ const urlsBugsInput = Runner.normalizeUrl(questionsOutputResult.urlsBugs, 'generic')['sanitized'];
1439
+ const urlsLicenseInput = Runner.normalizeUrl(questionsOutputResult.urlsLicense, 'generic')['sanitized'];
1440
+ const urlsLogoInput = Runner.normalizeUrl(questionsOutputResult.urlsLogo, 'generic')['sanitized'];
1441
+ const urlsDocumentationInput = Runner.normalizeUrl(questionsOutputResult.urlsDocumentation, 'generic')['sanitized'];
1442
+ const urlsNpmInput = Runner.normalizeUrl(questionsOutputResult.urlsNpm, 'generic')['sanitized'];
1443
+ const urlsDockerInput = Runner.normalizeUrl(questionsOutputResult.urlsDocker, 'generic')['sanitized'];
1444
+ const urlsFundSourcesInput = Runner.normalizeUrlArray(questionsOutputResult.urlsFundSources, 'generic')['sanitized'];
1445
+ const urlsPrivacyPolicyInput = Runner.normalizeUrl(questionsOutputResult.urlsPrivacyPolicy, 'generic')['sanitized'];
1446
+ const urlsTermsOfUseInput = Runner.normalizeUrl(questionsOutputResult.urlsTermsOfUse, 'generic')['sanitized'];
916
1447
  if (urlsHomepageInput !== undefined) {
917
1448
  urls.homepage = urlsHomepageInput;
918
1449
  }
@@ -949,12 +1480,6 @@ export class CliUtilityInitialize {
949
1480
  else {
950
1481
  Reflect.deleteProperty(urls, 'documentation');
951
1482
  }
952
- if (urlsGithubInput !== undefined) {
953
- urls.github = urlsGithubInput;
954
- }
955
- else {
956
- Reflect.deleteProperty(urls, 'github');
957
- }
958
1483
  if (urlsNpmInput !== undefined) {
959
1484
  urls.npm = urlsNpmInput;
960
1485
  }
@@ -992,7 +1517,7 @@ export class CliUtilityInitialize {
992
1517
  Reflect.deleteProperty(config, 'urls');
993
1518
  }
994
1519
  Logger.customize({
995
- name: 'CliUtilityInitialize.promptUrls',
1520
+ name: 'Runner.promptUrls',
996
1521
  purpose: 'updated',
997
1522
  padTop: 1,
998
1523
  padBottom: 1,
@@ -1106,7 +1631,7 @@ export class CliUtilityInitialize {
1106
1631
  kind: 'back',
1107
1632
  },
1108
1633
  });
1109
- const menuOutput = await CliUtilityInitialize.promptWithCancel({
1634
+ const menuOutput = await Runner.promptWithCancel({
1110
1635
  type: 'select',
1111
1636
  name: 'action',
1112
1637
  message: (workflows.length > 0) ? 'Select a workflow to manage.' : 'No workflows found. Choose an option.',
@@ -1115,73 +1640,73 @@ export class CliUtilityInitialize {
1115
1640
  if (menuOutput['cancelled'] === true) {
1116
1641
  return 'back';
1117
1642
  }
1118
- const menuOutputResult = menuOutput['result'];
1119
- if (menuOutputResult.action === undefined
1120
- || menuOutputResult.action['kind'] === 'back') {
1643
+ const menuOutputResultValue = menuOutput['result'];
1644
+ if (menuOutputResultValue.action === undefined
1645
+ || menuOutputResultValue.action['kind'] === 'back') {
1121
1646
  sync();
1122
1647
  return 'back';
1123
1648
  }
1124
- if (menuOutputResult.action['kind'] === 'add') {
1125
- const result = await CliUtilityInitialize.promptWorkflowsForm(undefined, 'create', workflows, config);
1649
+ if (menuOutputResultValue.action['kind'] === 'add') {
1650
+ const result = await Runner.promptWorkflowsForm(undefined, 'create', workflows, config);
1126
1651
  if (result['action'] === 'back') {
1127
1652
  continue;
1128
1653
  }
1129
1654
  workflows.push(result['workflow']);
1130
1655
  sync();
1131
1656
  Logger.customize({
1132
- name: 'CliUtilityInitialize.promptWorkflows',
1657
+ name: 'Runner.promptWorkflows',
1133
1658
  purpose: 'add',
1134
1659
  padTop: 1,
1135
1660
  padBottom: 1,
1136
1661
  }).info('Added new workflow.');
1137
1662
  continue;
1138
1663
  }
1139
- if (menuOutputResult.action['kind'] === 'edit') {
1140
- const workflowIndex = menuOutputResult.action['index'];
1664
+ if (menuOutputResultValue.action['kind'] === 'edit') {
1665
+ const workflowIndex = menuOutputResultValue.action['index'];
1141
1666
  if (workflowIndex < 0 || workflowIndex >= workflows.length) {
1142
1667
  continue;
1143
1668
  }
1144
1669
  const workflowToEdit = workflows[workflowIndex];
1145
- const workflowResult = await CliUtilityInitialize.promptWorkflowsForm(workflowToEdit, 'update', workflows, config);
1670
+ const workflowResult = await Runner.promptWorkflowsForm(workflowToEdit, 'update', workflows, config);
1146
1671
  if (workflowResult['action'] === 'back') {
1147
1672
  continue;
1148
1673
  }
1149
1674
  Reflect.set(workflows, workflowIndex, workflowResult['workflow']);
1150
1675
  sync();
1151
1676
  Logger.customize({
1152
- name: 'CliUtilityInitialize.promptWorkflows',
1677
+ name: 'Runner.promptWorkflows',
1153
1678
  purpose: 'edit',
1154
1679
  padTop: 1,
1155
1680
  padBottom: 1,
1156
1681
  }).info('Updated workflow.');
1157
1682
  continue;
1158
1683
  }
1159
- if (menuOutputResult.action['kind'] === 'remove') {
1160
- const workflowIndex = menuOutputResult.action['index'];
1161
- if (workflowIndex < 0 || workflowIndex >= workflows.length) {
1684
+ if (menuOutputResultValue.action['kind'] === 'remove') {
1685
+ const removeWorkflowIndex = menuOutputResultValue.action['index'];
1686
+ if (removeWorkflowIndex < 0 || removeWorkflowIndex >= workflows.length) {
1162
1687
  continue;
1163
1688
  }
1164
- const workflowToRemove = workflows[workflowIndex];
1689
+ const workflowToRemove = workflows[removeWorkflowIndex];
1165
1690
  if (workflowToRemove === undefined) {
1166
1691
  continue;
1167
1692
  }
1168
- const template = (typeof workflowToRemove['template'] === 'string') ? workflowToRemove['template'].trim() : '';
1169
- const suffix = (typeof workflowToRemove['suffix'] === 'string') ? workflowToRemove['suffix'].trim() : '';
1170
- let workflowLabel = `Workflow ${workflowIndex + 1}`;
1171
- if (template !== '' && suffix !== '') {
1172
- workflowLabel = `${template}-${suffix}`;
1693
+ const removeTemplate = (typeof workflowToRemove['template'] === 'string') ? workflowToRemove['template'].trim() : '';
1694
+ const removeSuffix = (typeof workflowToRemove['suffix'] === 'string') ? workflowToRemove['suffix'].trim() : '';
1695
+ let workflowLabel = `Workflow ${removeWorkflowIndex + 1}`;
1696
+ if (removeTemplate !== '' && removeSuffix !== '') {
1697
+ workflowLabel = `${removeTemplate}-${removeSuffix}`;
1173
1698
  }
1174
- else if (template !== '') {
1175
- workflowLabel = template;
1699
+ else if (removeTemplate !== '') {
1700
+ workflowLabel = removeTemplate;
1176
1701
  }
1177
- const shouldRemove = await CliUtilityInitialize.promptWorkflowsDeleteForm(workflowLabel);
1702
+ const shouldRemove = await Runner.promptWorkflowsDeleteForm(workflowLabel);
1178
1703
  if (shouldRemove !== true) {
1179
1704
  continue;
1180
1705
  }
1181
- workflows.splice(workflowIndex, 1);
1706
+ workflows.splice(removeWorkflowIndex, 1);
1182
1707
  sync();
1183
1708
  Logger.customize({
1184
- name: 'CliUtilityInitialize.promptWorkflows',
1709
+ name: 'Runner.promptWorkflows',
1185
1710
  purpose: 'remove',
1186
1711
  padTop: 1,
1187
1712
  padBottom: 1,
@@ -1208,7 +1733,7 @@ export class CliUtilityInitialize {
1208
1733
  templateInitialIndex = foundIndex;
1209
1734
  }
1210
1735
  }
1211
- const templateOutput = await CliUtilityInitialize.promptWithCancel({
1736
+ const templateOutput = await Runner.promptWithCancel({
1212
1737
  type: 'select',
1213
1738
  name: 'template',
1214
1739
  message: 'Select a workflow template.',
@@ -1220,9 +1745,9 @@ export class CliUtilityInitialize {
1220
1745
  action: 'back',
1221
1746
  };
1222
1747
  }
1223
- const templateOutputResult = templateOutput['result'];
1224
- const selectedTemplate = templateOutputResult.template;
1225
- const suffixOutput = await CliUtilityInitialize.promptWithCancel({
1748
+ const templateOutputResultValue = templateOutput['result'];
1749
+ const selectedTemplate = templateOutputResultValue.template;
1750
+ const suffixOutput = await Runner.promptWithCancel({
1226
1751
  type: 'text',
1227
1752
  name: 'suffix',
1228
1753
  message: 'Workflow suffix (used in filename and workflow name)',
@@ -1252,8 +1777,8 @@ export class CliUtilityInitialize {
1252
1777
  action: 'back',
1253
1778
  };
1254
1779
  }
1255
- const suffixOutputResult = suffixOutput['result'];
1256
- const selectedSuffix = (typeof suffixOutputResult.suffix === 'string') ? suffixOutputResult.suffix.trim() : '';
1780
+ const suffixOutputResultValue = suffixOutput['result'];
1781
+ const selectedSuffix = (typeof suffixOutputResultValue.suffix === 'string') ? suffixOutputResultValue.suffix.trim() : '';
1257
1782
  const triggersDir = join(resolveTemplatePath(import.meta.url, 'generators/github/workflows'), selectedTemplate, 'triggers');
1258
1783
  const triggersDirExists = await pathExists(triggersDir);
1259
1784
  let selectedTriggers = [];
@@ -1267,7 +1792,7 @@ export class CliUtilityInitialize {
1267
1792
  selected: existingTriggers.includes(triggerName),
1268
1793
  };
1269
1794
  });
1270
- const triggersOutput = await CliUtilityInitialize.promptWithCancel({
1795
+ const triggersOutput = await Runner.promptWithCancel({
1271
1796
  type: 'multiselect',
1272
1797
  name: 'triggers',
1273
1798
  message: 'Select triggers for this workflow.',
@@ -1278,12 +1803,12 @@ export class CliUtilityInitialize {
1278
1803
  action: 'back',
1279
1804
  };
1280
1805
  }
1281
- const triggersOutputResult = triggersOutput['result'];
1282
- selectedTriggers = (Array.isArray(triggersOutputResult.triggers) === true) ? triggersOutputResult.triggers : [];
1806
+ const triggersOutputResultValue = triggersOutput['result'];
1807
+ selectedTriggers = (Array.isArray(triggersOutputResultValue.triggers) === true) ? triggersOutputResultValue.triggers : [];
1283
1808
  const scheduleVariants = selectedTriggers.filter((trigger) => trigger.startsWith('schedule-'));
1284
1809
  if (scheduleVariants.length > 1) {
1285
1810
  Logger.customize({
1286
- name: 'CliUtilityInitialize.promptWorkflowsForm',
1811
+ name: 'Runner.promptWorkflowsForm',
1287
1812
  purpose: 'validation',
1288
1813
  padTop: 1,
1289
1814
  padBottom: 1,
@@ -1300,15 +1825,15 @@ export class CliUtilityInitialize {
1300
1825
  && typeof w['template'] === 'string'
1301
1826
  && w['template'].trim() !== '')
1302
1827
  .map((w) => {
1303
- const compositeKey = (typeof w['suffix'] === 'string' && w['suffix'].trim() !== '') ? `${w['template']}-${w['suffix']}` : w['template'];
1828
+ const dependsOnKey = (typeof w['suffix'] === 'string' && w['suffix'].trim() !== '') ? `${w['template']}-${w['suffix']}` : w['template'];
1304
1829
  return {
1305
- title: compositeKey,
1306
- value: compositeKey,
1307
- selected: existingDependsOn.includes(compositeKey),
1830
+ title: dependsOnKey,
1831
+ value: dependsOnKey,
1832
+ selected: existingDependsOn.includes(dependsOnKey),
1308
1833
  };
1309
1834
  });
1310
1835
  if (dependsOnChoices.length > 0) {
1311
- const dependsOnOutput = await CliUtilityInitialize.promptWithCancel({
1836
+ const dependsOnOutput = await Runner.promptWithCancel({
1312
1837
  type: 'multiselect',
1313
1838
  name: 'dependsOn',
1314
1839
  message: 'Select the workflows this depends on.',
@@ -1319,8 +1844,8 @@ export class CliUtilityInitialize {
1319
1844
  action: 'back',
1320
1845
  };
1321
1846
  }
1322
- const dependsOnOutputResult = dependsOnOutput['result'];
1323
- selectedDependsOn = (Array.isArray(dependsOnOutputResult.dependsOn) === true && dependsOnOutputResult.dependsOn.length > 0) ? dependsOnOutputResult.dependsOn : undefined;
1847
+ const dependsOnOutputResultValue = dependsOnOutput['result'];
1848
+ selectedDependsOn = (Array.isArray(dependsOnOutputResultValue.dependsOn) === true && dependsOnOutputResultValue.dependsOn.length > 0) ? dependsOnOutputResultValue.dependsOn : undefined;
1324
1849
  }
1325
1850
  }
1326
1851
  const matchedMetadata = libWorkflowTemplatesMetadata.find((entry) => entry['name'] === selectedTemplate);
@@ -1365,7 +1890,7 @@ export class CliUtilityInitialize {
1365
1890
  kind: 'done',
1366
1891
  },
1367
1892
  });
1368
- const targetMenuOutput = await CliUtilityInitialize.promptWithCancel({
1893
+ const targetMenuOutput = await Runner.promptWithCancel({
1369
1894
  type: 'select',
1370
1895
  name: 'targetAction',
1371
1896
  message: (selectedTargets.length > 0) ? 'Select a target to manage.' : 'No targets added yet. Choose an option.',
@@ -1376,8 +1901,8 @@ export class CliUtilityInitialize {
1376
1901
  action: 'back',
1377
1902
  };
1378
1903
  }
1379
- const targetMenuOutputResult = targetMenuOutput['result'];
1380
- const targetMenuAction = targetMenuOutputResult.targetAction;
1904
+ const targetMenuOutputResultValue = targetMenuOutput['result'];
1905
+ const targetMenuAction = targetMenuOutputResultValue.targetAction;
1381
1906
  if (targetMenuAction['kind'] === 'done') {
1382
1907
  break;
1383
1908
  }
@@ -1396,7 +1921,7 @@ export class CliUtilityInitialize {
1396
1921
  title: availableTargetType,
1397
1922
  value: availableTargetType,
1398
1923
  }));
1399
- const targetTypeOutput = await CliUtilityInitialize.promptWithCancel({
1924
+ const targetTypeOutput = await Runner.promptWithCancel({
1400
1925
  type: 'select',
1401
1926
  name: 'targetType',
1402
1927
  message: 'Select a target type.',
@@ -1406,14 +1931,14 @@ export class CliUtilityInitialize {
1406
1931
  if (targetTypeOutput['cancelled'] === true) {
1407
1932
  continue;
1408
1933
  }
1409
- const targetTypeOutputResult = targetTypeOutput['result'];
1410
- const selectedTargetType = targetTypeOutputResult.targetType;
1934
+ const targetTypeOutputResultValue = targetTypeOutput['result'];
1935
+ const selectedTargetType = targetTypeOutputResultValue.targetType;
1411
1936
  const targetWorkingDirInitial = (targetToEdit !== undefined) ? workspaceKeys.indexOf(targetToEdit['workingDir']) : 0;
1412
1937
  const targetWorkingDirChoices = workspaceKeys.map((workspaceKey) => ({
1413
1938
  title: workspaceKey,
1414
1939
  value: workspaceKey,
1415
1940
  }));
1416
- const targetWorkingDirOutput = await CliUtilityInitialize.promptWithCancel({
1941
+ const targetWorkingDirOutput = await Runner.promptWithCancel({
1417
1942
  type: 'select',
1418
1943
  name: 'targetWorkingDir',
1419
1944
  message: 'Select a working directory.',
@@ -1423,8 +1948,8 @@ export class CliUtilityInitialize {
1423
1948
  if (targetWorkingDirOutput['cancelled'] === true) {
1424
1949
  continue;
1425
1950
  }
1426
- const targetWorkingDirOutputResult = targetWorkingDirOutput['result'];
1427
- const selectedTargetWorkingDir = targetWorkingDirOutputResult.targetWorkingDir;
1951
+ const targetWorkingDirOutputResultValue = targetWorkingDirOutput['result'];
1952
+ const selectedTargetWorkingDir = targetWorkingDirOutputResultValue.targetWorkingDir;
1428
1953
  const targetIsDuplicate = selectedTargets.some((selectedTarget, selectedTargetIndex) => {
1429
1954
  if (selectedTargetIndex === targetEditIndex) {
1430
1955
  return false;
@@ -1433,7 +1958,7 @@ export class CliUtilityInitialize {
1433
1958
  });
1434
1959
  if (targetIsDuplicate === true) {
1435
1960
  Logger.customize({
1436
- name: 'CliUtilityInitialize.promptWorkflowsForm',
1961
+ name: 'Runner.promptWorkflowsForm',
1437
1962
  purpose: 'validation',
1438
1963
  padTop: 1,
1439
1964
  padBottom: 1,
@@ -1454,7 +1979,7 @@ export class CliUtilityInitialize {
1454
1979
  selected: targetToEditExistingNeeds.includes(candidate['workingDir']),
1455
1980
  }));
1456
1981
  if (targetNeedsChoices.length > 0) {
1457
- const targetNeedsOutput = await CliUtilityInitialize.promptWithCancel({
1982
+ const targetNeedsOutput = await Runner.promptWithCancel({
1458
1983
  type: 'multiselect',
1459
1984
  name: 'targetNeeds',
1460
1985
  message: 'Select targets this must wait for before publishing (optional).',
@@ -1463,8 +1988,8 @@ export class CliUtilityInitialize {
1463
1988
  if (targetNeedsOutput['cancelled'] === true) {
1464
1989
  continue;
1465
1990
  }
1466
- const targetNeedsOutputResult = targetNeedsOutput['result'];
1467
- selectedTargetNeeds = (Array.isArray(targetNeedsOutputResult.targetNeeds) === true && targetNeedsOutputResult.targetNeeds.length > 0) ? targetNeedsOutputResult.targetNeeds : undefined;
1991
+ const targetNeedsOutputResultValue = targetNeedsOutput['result'];
1992
+ selectedTargetNeeds = (Array.isArray(targetNeedsOutputResultValue.targetNeeds) === true && targetNeedsOutputResultValue.targetNeeds.length > 0) ? targetNeedsOutputResultValue.targetNeeds : undefined;
1468
1993
  }
1469
1994
  const newTarget = {
1470
1995
  type: selectedTargetType,
@@ -1494,7 +2019,7 @@ export class CliUtilityInitialize {
1494
2019
  value: workspaceKey,
1495
2020
  selected: existingScopes.includes(workspaceKey),
1496
2021
  }));
1497
- const scopesOutput = await CliUtilityInitialize.promptWithCancel({
2022
+ const scopesOutput = await Runner.promptWithCancel({
1498
2023
  type: 'multiselect',
1499
2024
  name: 'scopes',
1500
2025
  message: 'Select any EXTRA workspaces to check and build for this workflow.',
@@ -1505,8 +2030,8 @@ export class CliUtilityInitialize {
1505
2030
  action: 'back',
1506
2031
  };
1507
2032
  }
1508
- const scopesOutputResult = scopesOutput['result'];
1509
- const extraScopes = (Array.isArray(scopesOutputResult.scopes) === true) ? scopesOutputResult.scopes : [];
2033
+ const scopesOutputResultValue = scopesOutput['result'];
2034
+ const extraScopes = (Array.isArray(scopesOutputResultValue.scopes) === true) ? scopesOutputResultValue.scopes : [];
1510
2035
  for (const extraScope of extraScopes) {
1511
2036
  if (selectedScopes.includes(extraScope) === false) {
1512
2037
  selectedScopes.push(extraScope);
@@ -1517,8 +2042,10 @@ export class CliUtilityInitialize {
1517
2042
  const settings = {};
1518
2043
  if (matchedMetadata !== undefined) {
1519
2044
  const mergedVariables = { ...matchedMetadata['variables'] };
2045
+ const variableNameToTargetWorkingDir = {};
1520
2046
  for (const selectedTarget of selectedTargets) {
1521
2047
  const targetType = selectedTarget['type'];
2048
+ const targetWorkingDir = selectedTarget['workingDir'];
1522
2049
  const targetMetadata = matchedMetadata['targets'] ?? {};
1523
2050
  const targetVariables = (targetMetadata[targetType] !== undefined) ? targetMetadata[targetType]['variables'] : {};
1524
2051
  const targetVarEntries = Object.entries(targetVariables);
@@ -1529,6 +2056,13 @@ export class CliUtilityInitialize {
1529
2056
  Reflect.set(mergedVariables, targetVarKey, targetVarValue);
1530
2057
  }
1531
2058
  }
2059
+ const targetVariableNames = Object.keys(targetVariables);
2060
+ for (const targetVariableName of targetVariableNames) {
2061
+ const targetVariableNameKey = targetVariableName;
2062
+ if (variableNameToTargetWorkingDir[targetVariableNameKey] === undefined) {
2063
+ Reflect.set(variableNameToTargetWorkingDir, targetVariableNameKey, targetWorkingDir);
2064
+ }
2065
+ }
1532
2066
  }
1533
2067
  const variableEntries = Object.entries(mergedVariables);
1534
2068
  for (const variableEntry of variableEntries) {
@@ -1551,8 +2085,14 @@ export class CliUtilityInitialize {
1551
2085
  if (typeof variableConfig['description'] === 'string') {
1552
2086
  parts.push(variableConfig['description']);
1553
2087
  }
1554
- if (typeof variableConfig['example'] === 'string') {
1555
- parts.push(`e.g. ${variableConfig['example']}`);
2088
+ const exampleRaw = variableConfig['example'];
2089
+ const exampleWorkingDir = variableNameToTargetWorkingDir[variableName];
2090
+ let exampleResolved = exampleRaw;
2091
+ if (typeof exampleResolved === 'string' && typeof exampleWorkingDir === 'string') {
2092
+ exampleResolved = exampleResolved.replaceAll('{workingDir}', exampleWorkingDir);
2093
+ }
2094
+ if (typeof exampleResolved === 'string') {
2095
+ parts.push(`e.g. ${exampleResolved}`);
1556
2096
  }
1557
2097
  if (parts.length > 0) {
1558
2098
  promptMessage = `${promptMessage} (${parts.join(', ')})`;
@@ -1562,19 +2102,20 @@ export class CliUtilityInitialize {
1562
2102
  && typeof workflow['settings'][variableName] === 'string') {
1563
2103
  initialValue = workflow['settings'][variableName];
1564
2104
  }
1565
- const settingsOutput = await CliUtilityInitialize.promptWithCancel({
2105
+ const settingsOutput = await Runner.promptWithCancel({
1566
2106
  type: 'text',
1567
2107
  name: 'settingValue',
1568
2108
  message: promptMessage,
1569
2109
  initial: initialValue,
2110
+ validate: (variableConfig['format'] === 'literal') ? Runner['isNonEmptyLiteralInput'] : undefined,
1570
2111
  });
1571
2112
  if (settingsOutput['cancelled'] === true) {
1572
2113
  return {
1573
2114
  action: 'back',
1574
2115
  };
1575
2116
  }
1576
- const settingsOutputResult = settingsOutput['result'];
1577
- const settingValue = (typeof settingsOutputResult.settingValue === 'string') ? settingsOutputResult.settingValue.trim().replaceAll('\\n', '\n') : '';
2117
+ const settingsOutputResultValue = settingsOutput['result'];
2118
+ const settingValue = (typeof settingsOutputResultValue.settingValue === 'string') ? settingsOutputResultValue.settingValue.trim().replaceAll('\\n', '\n') : '';
1578
2119
  if (settingValue !== '') {
1579
2120
  Reflect.set(settings, variableName, settingValue);
1580
2121
  }
@@ -1608,7 +2149,7 @@ export class CliUtilityInitialize {
1608
2149
  };
1609
2150
  }
1610
2151
  static async promptWorkflowsDeleteForm(label) {
1611
- const confirmOutput = await CliUtilityInitialize.promptWithCancel({
2152
+ const confirmOutput = await Runner.promptWithCancel({
1612
2153
  type: 'confirm',
1613
2154
  name: 'confirm',
1614
2155
  message: `Remove workflow "${label}"?`,
@@ -1632,7 +2173,7 @@ export class CliUtilityInitialize {
1632
2173
  return `./${relativePath.split(sep).join('/')}`;
1633
2174
  });
1634
2175
  Logger.customize({
1635
- name: 'CliUtilityInitialize.promptWorkspaces',
2176
+ name: 'Runner.promptWorkspaces',
1636
2177
  purpose: 'paths',
1637
2178
  }).debug(workspacePaths);
1638
2179
  while (true) {
@@ -1659,7 +2200,7 @@ export class CliUtilityInitialize {
1659
2200
  description: 'Return to the category selection.',
1660
2201
  value: 'back',
1661
2202
  });
1662
- const menuOutput = await CliUtilityInitialize.promptWithCancel({
2203
+ const menuOutput = await Runner.promptWithCancel({
1663
2204
  type: 'select',
1664
2205
  name: 'workspacePath',
1665
2206
  message: 'Select a workspace to configure.',
@@ -1674,7 +2215,7 @@ export class CliUtilityInitialize {
1674
2215
  return 'back';
1675
2216
  }
1676
2217
  const workspacePath = menuOutputResult.workspacePath;
1677
- const formResult = await CliUtilityInitialize.promptWorkspacesForm({
2218
+ const formResult = await Runner.promptWorkspacesForm({
1678
2219
  workspacePath,
1679
2220
  existingWorkspace: workspaces[workspacePath],
1680
2221
  projectSlug: (config['project'] !== undefined && config['project']['name'] !== undefined) ? config['project']['name']['slug'] : undefined,
@@ -1685,7 +2226,7 @@ export class CliUtilityInitialize {
1685
2226
  Reflect.set(workspaces, workspacePath, formResult['workspace']);
1686
2227
  Object.assign(config, { workspaces });
1687
2228
  Logger.customize({
1688
- name: 'CliUtilityInitialize.promptWorkspaces',
2229
+ name: 'Runner.promptWorkspaces',
1689
2230
  purpose: 'updated',
1690
2231
  padTop: 1,
1691
2232
  padBottom: 1,
@@ -1752,20 +2293,23 @@ export class CliUtilityInitialize {
1752
2293
  return `${options['projectSlug']}-${role}`;
1753
2294
  }
1754
2295
  const base = (options['projectSlug'] !== undefined) ? `${options['projectSlug']}-${role}` : role;
1755
- const namePrompt = await CliUtilityInitialize.promptWithCancel({
2296
+ const validateWorkspaceName = (workspaceNameValue) => {
2297
+ return Runner.normalizeWorkspaceName(workspaceNameValue, role, base)['result'];
2298
+ };
2299
+ const namePrompt = await Runner.promptWithCancel({
1756
2300
  type: 'text',
1757
2301
  name: 'workspaceName',
1758
2302
  message: 'Workspace package name',
1759
2303
  initial: (options['existingWorkspace'] !== undefined) ? options['existingWorkspace']['name'] ?? '' : '',
1760
- validate: (value) => CliUtilityInitialize.normalizeWorkspaceName(value, role, base)['result'],
2304
+ validate: validateWorkspaceName,
1761
2305
  });
1762
2306
  if (namePrompt['cancelled'] === true) {
1763
2307
  return undefined;
1764
2308
  }
1765
- return CliUtilityInitialize.normalizeWorkspaceName(namePrompt['result'].workspaceName, role, base)['sanitized'];
2309
+ return Runner.normalizeWorkspaceName(namePrompt['result'].workspaceName, role, base)['sanitized'];
1766
2310
  };
1767
2311
  const existingRoleIndex = allowedRoles.findIndex((allowedRole) => options['existingWorkspace'] !== undefined && allowedRole['value'] === options['existingWorkspace']['role']);
1768
- const rolePrompt = await CliUtilityInitialize.promptWithCancel({
2312
+ const rolePrompt = await Runner.promptWithCancel({
1769
2313
  type: 'select',
1770
2314
  name: 'workspaceRole',
1771
2315
  message: `Select a role for "${options['workspacePath']}"`,
@@ -1786,7 +2330,7 @@ export class CliUtilityInitialize {
1786
2330
  const selectedRole = rolePrompt['result'].workspaceRole;
1787
2331
  const allowedPolicies = libItemAllowedPoliciesByRole[selectedRole];
1788
2332
  const existingPolicyIndex = allowedPolicies.findIndex((allowedPolicy) => options['existingWorkspace'] !== undefined && allowedPolicy === options['existingWorkspace']['policy']);
1789
- const policyPrompt = await CliUtilityInitialize.promptWithCancel({
2333
+ const policyPrompt = await Runner.promptWithCancel({
1790
2334
  type: 'select',
1791
2335
  name: 'workspacePolicy',
1792
2336
  message: 'Select a policy',
@@ -1812,8 +2356,24 @@ export class CliUtilityInitialize {
1812
2356
  action: 'back',
1813
2357
  };
1814
2358
  }
2359
+ const validateWorkspaceDisplayName = (workspaceDisplayNameValue) => {
2360
+ return Runner.normalizeText(workspaceDisplayNameValue, Infinity)['result'];
2361
+ };
2362
+ const displayNamePrompt = await Runner.promptWithCancel({
2363
+ type: 'text',
2364
+ name: 'workspaceDisplayName',
2365
+ message: 'Workspace display name (optional)',
2366
+ initial: (options['existingWorkspace'] !== undefined) ? options['existingWorkspace']['displayName'] ?? '' : '',
2367
+ validate: validateWorkspaceDisplayName,
2368
+ });
2369
+ if (displayNamePrompt['cancelled'] === true) {
2370
+ return {
2371
+ action: 'back',
2372
+ };
2373
+ }
2374
+ const workspaceDisplayNameInput = Runner.normalizeText(displayNamePrompt['result'].workspaceDisplayName, Infinity)['sanitized'];
1815
2375
  const existingRecipes = (options['existingWorkspace'] !== undefined && options['existingWorkspace']['recipes'] !== undefined) ? options['existingWorkspace']['recipes'] : undefined;
1816
- const recipesPrompt = await CliUtilityInitialize.promptWithCancel({
2376
+ const recipesPrompt = await Runner.promptWithCancel({
1817
2377
  type: 'multiselect',
1818
2378
  name: 'workspaceRecipes',
1819
2379
  message: 'Select recipes to enable',
@@ -1841,7 +2401,7 @@ export class CliUtilityInitialize {
1841
2401
  const existingTuple = (Array.isArray(existingTupleRaw) === true) ? existingTupleRaw : undefined;
1842
2402
  const existingSettings = (existingTuple !== undefined && existingTuple.length > 1) ? existingTuple[1] : undefined;
1843
2403
  if (recipe === 'sync-identity' && selectedPolicy === 'distributable') {
1844
- const settingsPrompt = await CliUtilityInitialize.promptWithCancel({
2404
+ const identitySettingsPrompt = await Runner.promptWithCancel({
1845
2405
  type: 'multiselect',
1846
2406
  name: 'workspaceRecipeSettings',
1847
2407
  message: 'sync-identity: Select properties to sync',
@@ -1858,20 +2418,20 @@ export class CliUtilityInitialize {
1858
2418
  },
1859
2419
  ],
1860
2420
  });
1861
- if (settingsPrompt['cancelled'] === true) {
2421
+ if (identitySettingsPrompt['cancelled'] === true) {
1862
2422
  return {
1863
2423
  action: 'back',
1864
2424
  };
1865
2425
  }
1866
- const selectedSettings = settingsPrompt['result'].workspaceRecipeSettings;
1867
- if (selectedSettings.length > 0) {
1868
- const settings = {};
1869
- for (const setting of selectedSettings) {
1870
- Reflect.set(settings, setting, true);
2426
+ const identitySelectedSettings = identitySettingsPrompt['result'].workspaceRecipeSettings;
2427
+ if (identitySelectedSettings.length > 0) {
2428
+ const identitySettings = {};
2429
+ for (const setting of identitySelectedSettings) {
2430
+ Reflect.set(identitySettings, setting, true);
1871
2431
  }
1872
2432
  Reflect.set(recipes, recipe, [
1873
2433
  true,
1874
- settings,
2434
+ identitySettings,
1875
2435
  ]);
1876
2436
  }
1877
2437
  else {
@@ -1879,7 +2439,7 @@ export class CliUtilityInitialize {
1879
2439
  }
1880
2440
  }
1881
2441
  else if (recipe === 'sync-ownership' && selectedPolicy === 'distributable') {
1882
- const settingsPrompt = await CliUtilityInitialize.promptWithCancel({
2442
+ const ownershipSettingsPrompt = await Runner.promptWithCancel({
1883
2443
  type: 'multiselect',
1884
2444
  name: 'workspaceRecipeSettings',
1885
2445
  message: 'sync-ownership: Select properties to sync',
@@ -1916,20 +2476,20 @@ export class CliUtilityInitialize {
1916
2476
  },
1917
2477
  ],
1918
2478
  });
1919
- if (settingsPrompt['cancelled'] === true) {
2479
+ if (ownershipSettingsPrompt['cancelled'] === true) {
1920
2480
  return {
1921
2481
  action: 'back',
1922
2482
  };
1923
2483
  }
1924
- const selectedSettings = settingsPrompt['result'].workspaceRecipeSettings;
1925
- if (selectedSettings.length > 0) {
1926
- const settings = {};
1927
- for (const setting of selectedSettings) {
1928
- Reflect.set(settings, setting, true);
2484
+ const ownershipSelectedSettings = ownershipSettingsPrompt['result'].workspaceRecipeSettings;
2485
+ if (ownershipSelectedSettings.length > 0) {
2486
+ const ownershipSettings = {};
2487
+ for (const setting of ownershipSelectedSettings) {
2488
+ Reflect.set(ownershipSettings, setting, true);
1929
2489
  }
1930
2490
  Reflect.set(recipes, recipe, [
1931
2491
  true,
1932
- settings,
2492
+ ownershipSettings,
1933
2493
  ]);
1934
2494
  }
1935
2495
  else {
@@ -1937,7 +2497,7 @@ export class CliUtilityInitialize {
1937
2497
  }
1938
2498
  }
1939
2499
  else if (recipe === 'sync-environment') {
1940
- const settingsPrompt = await CliUtilityInitialize.promptWithCancel({
2500
+ const environmentSettingsPrompt = await Runner.promptWithCancel({
1941
2501
  type: 'multiselect',
1942
2502
  name: 'workspaceRecipeSettings',
1943
2503
  message: 'sync-environment: Select settings',
@@ -1947,20 +2507,20 @@ export class CliUtilityInitialize {
1947
2507
  selected: existingSettings !== undefined && existingSettings['trackNodeLtsVersions'] === true,
1948
2508
  }],
1949
2509
  });
1950
- if (settingsPrompt['cancelled'] === true) {
2510
+ if (environmentSettingsPrompt['cancelled'] === true) {
1951
2511
  return {
1952
2512
  action: 'back',
1953
2513
  };
1954
2514
  }
1955
- const selectedSettings = settingsPrompt['result'].workspaceRecipeSettings;
1956
- if (selectedSettings.length > 0) {
1957
- const settings = {};
1958
- for (const setting of selectedSettings) {
1959
- Reflect.set(settings, setting, true);
2515
+ const environmentSelectedSettings = environmentSettingsPrompt['result'].workspaceRecipeSettings;
2516
+ if (environmentSelectedSettings.length > 0) {
2517
+ const environmentSettings = {};
2518
+ for (const setting of environmentSelectedSettings) {
2519
+ Reflect.set(environmentSettings, setting, true);
1960
2520
  }
1961
2521
  Reflect.set(recipes, recipe, [
1962
2522
  true,
1963
- settings,
2523
+ environmentSettings,
1964
2524
  ]);
1965
2525
  }
1966
2526
  else {
@@ -1968,7 +2528,7 @@ export class CliUtilityInitialize {
1968
2528
  }
1969
2529
  }
1970
2530
  else if (recipe === 'cleanup') {
1971
- const settingsPrompt = await CliUtilityInitialize.promptWithCancel({
2531
+ const cleanupSettingsPrompt = await Runner.promptWithCancel({
1972
2532
  type: 'multiselect',
1973
2533
  name: 'workspaceRecipeSettings',
1974
2534
  message: 'cleanup: Select settings',
@@ -1985,20 +2545,20 @@ export class CliUtilityInitialize {
1985
2545
  },
1986
2546
  ],
1987
2547
  });
1988
- if (settingsPrompt['cancelled'] === true) {
2548
+ if (cleanupSettingsPrompt['cancelled'] === true) {
1989
2549
  return {
1990
2550
  action: 'back',
1991
2551
  };
1992
2552
  }
1993
- const selectedSettings = settingsPrompt['result'].workspaceRecipeSettings;
1994
- if (selectedSettings.length > 0) {
1995
- const settings = {};
1996
- for (const setting of selectedSettings) {
1997
- Reflect.set(settings, setting, true);
2553
+ const cleanupSelectedSettings = cleanupSettingsPrompt['result'].workspaceRecipeSettings;
2554
+ if (cleanupSelectedSettings.length > 0) {
2555
+ const cleanupSettings = {};
2556
+ for (const setting of cleanupSelectedSettings) {
2557
+ Reflect.set(cleanupSettings, setting, true);
1998
2558
  }
1999
2559
  Reflect.set(recipes, recipe, [
2000
2560
  true,
2001
- settings,
2561
+ cleanupSettings,
2002
2562
  ]);
2003
2563
  }
2004
2564
  else {
@@ -2006,7 +2566,7 @@ export class CliUtilityInitialize {
2006
2566
  }
2007
2567
  }
2008
2568
  else if (recipe === 'normalize-dependencies') {
2009
- const settingsPrompt = await CliUtilityInitialize.promptWithCancel({
2569
+ const dependenciesSettingsPrompt = await Runner.promptWithCancel({
2010
2570
  type: 'multiselect',
2011
2571
  name: 'workspaceRecipeSettings',
2012
2572
  message: 'normalize-dependencies: Select settings',
@@ -2023,20 +2583,20 @@ export class CliUtilityInitialize {
2023
2583
  },
2024
2584
  ],
2025
2585
  });
2026
- if (settingsPrompt['cancelled'] === true) {
2586
+ if (dependenciesSettingsPrompt['cancelled'] === true) {
2027
2587
  return {
2028
2588
  action: 'back',
2029
2589
  };
2030
2590
  }
2031
- const selectedSettings = settingsPrompt['result'].workspaceRecipeSettings;
2032
- if (selectedSettings.length > 0) {
2033
- const settings = {};
2034
- for (const setting of selectedSettings) {
2035
- Reflect.set(settings, setting, true);
2591
+ const dependenciesSelectedSettings = dependenciesSettingsPrompt['result'].workspaceRecipeSettings;
2592
+ if (dependenciesSelectedSettings.length > 0) {
2593
+ const dependenciesSettings = {};
2594
+ for (const setting of dependenciesSelectedSettings) {
2595
+ Reflect.set(dependenciesSettings, setting, true);
2036
2596
  }
2037
2597
  Reflect.set(recipes, recipe, [
2038
2598
  true,
2039
- settings,
2599
+ dependenciesSettings,
2040
2600
  ]);
2041
2601
  }
2042
2602
  else {
@@ -2051,6 +2611,7 @@ export class CliUtilityInitialize {
2051
2611
  action: 'apply',
2052
2612
  workspace: {
2053
2613
  name: resolvedName,
2614
+ ...(workspaceDisplayNameInput !== undefined) ? { displayName: workspaceDisplayNameInput } : {},
2054
2615
  role: selectedRole,
2055
2616
  policy: selectedPolicy,
2056
2617
  ...(Object.keys(recipes).length > 0) ? { recipes } : {},
@@ -2078,7 +2639,7 @@ export class CliUtilityInitialize {
2078
2639
  static async checkPath(currentDirectory) {
2079
2640
  const locations = await discoverPathsWithFile('package.json', 'backward');
2080
2641
  Logger.customize({
2081
- name: 'CliUtilityInitialize.checkPath',
2642
+ name: 'Runner.checkPath',
2082
2643
  purpose: 'detectedLocations',
2083
2644
  }).debug(locations);
2084
2645
  if (locations.length < 1) {
@@ -2087,7 +2648,7 @@ export class CliUtilityInitialize {
2087
2648
  `Current directory is "${currentDirectory}"`,
2088
2649
  ].join('\n');
2089
2650
  Logger.customize({
2090
- name: 'CliUtilityInitialize.checkPath',
2651
+ name: 'Runner.checkPath',
2091
2652
  purpose: 'lessThanOne',
2092
2653
  }).error(lessThanOneMessage);
2093
2654
  return false;
@@ -2098,7 +2659,7 @@ export class CliUtilityInitialize {
2098
2659
  `Current directory is "${currentDirectory}"`,
2099
2660
  ].join('\n');
2100
2661
  Logger.customize({
2101
- name: 'CliUtilityInitialize.checkPath',
2662
+ name: 'Runner.checkPath',
2102
2663
  purpose: 'greaterThanOne',
2103
2664
  }).error(greaterThanOneMessage);
2104
2665
  return false;
@@ -2109,7 +2670,7 @@ export class CliUtilityInitialize {
2109
2670
  `Current directory is "${currentDirectory}"`,
2110
2671
  ].join('\n');
2111
2672
  Logger.customize({
2112
- name: 'CliUtilityInitialize.checkPath',
2673
+ name: 'Runner.checkPath',
2113
2674
  purpose: 'notProjectRootDirectory',
2114
2675
  }).error(notProjectRootDirectoryMessage);
2115
2676
  return false;
@@ -2211,7 +2772,7 @@ export class CliUtilityInitialize {
2211
2772
  .map((item) => item.trim())
2212
2773
  .filter((item) => item !== '');
2213
2774
  for (let i = 0; i < items.length; i += 1) {
2214
- const normalizedText = CliUtilityInitialize.normalizeText(items[i], maxLengthPerItem);
2775
+ const normalizedText = Runner.normalizeText(items[i], maxLengthPerItem);
2215
2776
  const result = normalizedText['result'];
2216
2777
  const sanitized = normalizedText['sanitized'];
2217
2778
  if (result !== true) {
@@ -2300,7 +2861,7 @@ export class CliUtilityInitialize {
2300
2861
  .map((item) => item.trim())
2301
2862
  .filter((item) => item !== '');
2302
2863
  for (let i = 0; i < items.length; i += 1) {
2303
- const normalizedUrl = CliUtilityInitialize.normalizeUrl(items[i], protocol);
2864
+ const normalizedUrl = Runner.normalizeUrl(items[i], protocol);
2304
2865
  const result = normalizedUrl['result'];
2305
2866
  const sanitized = normalizedUrl['sanitized'];
2306
2867
  if (result !== true) {