@askrjs/cli 0.0.2 → 0.0.4

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 (310) hide show
  1. package/README.md +46 -7
  2. package/dist/add.d.ts +16 -0
  3. package/dist/add.js +558 -1
  4. package/dist/cli.d.ts +5 -0
  5. package/dist/cli.js +43 -16
  6. package/dist/create.d.ts +5 -0
  7. package/dist/create.js +104 -26
  8. package/dist/directory-swap-DWoHtx7C.js +35 -0
  9. package/dist/discovery-Difb7Y4G.js +323 -0
  10. package/dist/generate.d.ts +5 -0
  11. package/dist/generate.js +461 -0
  12. package/dist/is-direct-execution-Cdlr-ZUl.js +0 -2
  13. package/dist/openapi.d.ts +25 -0
  14. package/dist/openapi.js +49 -16
  15. package/dist/planner-VAj7qlxr.js +285 -0
  16. package/dist/range-YUs9eimn.js +125 -0
  17. package/dist/registry-CyrRHRG5.js +209 -0
  18. package/dist/skills/askr-dashboard-charts/SKILL.md +61 -44
  19. package/dist/skills/askr-dashboard-charts/agents/openai.yaml +2 -2
  20. package/dist/skills/askr-ssr-ssg/SKILL.md +3 -1
  21. package/dist/{skills-Bh0mEhIx.js → skills-B7CbWur9.js} +89 -26
  22. package/dist/skills.d.ts +18 -0
  23. package/dist/skills.js +1 -1
  24. package/dist/specification-DXnDOC-0.js +49 -0
  25. package/dist/ssg-config.d.ts +41 -0
  26. package/dist/ssg-config.js +1 -0
  27. package/dist/ssg.d.ts +61 -0
  28. package/dist/ssg.js +360 -24
  29. package/dist/templates/full-stack/AGENTS.md +0 -1
  30. package/dist/templates/full-stack/README.md +0 -1
  31. package/dist/templates/full-stack/index.html +0 -1
  32. package/dist/templates/full-stack/package.json +5 -3
  33. package/dist/templates/full-stack/server.ts +5 -9
  34. package/dist/templates/full-stack/src/action-authorizations.ts +2 -2
  35. package/dist/templates/full-stack/src/actions/create-message.ts +5 -5
  36. package/dist/templates/full-stack/src/i18n.ts +4 -4
  37. package/dist/templates/full-stack/src/main.tsx +4 -5
  38. package/dist/templates/full-stack/src/pages/home.tsx +5 -5
  39. package/dist/templates/full-stack/src/pages/layout.tsx +15 -5
  40. package/dist/templates/full-stack/src/pages/not-found.tsx +5 -2
  41. package/dist/templates/full-stack/src/routes.tsx +11 -12
  42. package/dist/templates/full-stack/src/schemas.ts +1 -2
  43. package/dist/templates/full-stack/src/server/action-registry.ts +5 -10
  44. package/dist/templates/full-stack/src/server/actions/create-message.ts +4 -4
  45. package/dist/templates/full-stack/src/server/app.ts +67 -57
  46. package/dist/templates/full-stack/src/server/dependencies.ts +10 -10
  47. package/dist/templates/full-stack/src/server/entry-server.ts +3 -3
  48. package/dist/templates/full-stack/src/telemetry.ts +1 -2
  49. package/dist/templates/full-stack/tests/actions/create-message.test.ts +7 -8
  50. package/dist/templates/full-stack/tsconfig.json +1 -2
  51. package/dist/templates/full-stack/vite.config.ts +5 -6
  52. package/dist/templates/spa/AGENTS.md +1 -1
  53. package/dist/templates/spa/package.json +3 -4
  54. package/dist/templates/spa/src/adapters/operations-client.ts +7 -2
  55. package/dist/templates/spa/src/pages/app/_routes.tsx +2 -0
  56. package/dist/templates/spa/src/pages/app/admin-home.tsx +21 -3
  57. package/dist/templates/spa/src/pages/public/_routes.tsx +2 -0
  58. package/dist/templates/spa/src/styles.css +1 -1
  59. package/dist/templates/spa/tsconfig.json +2 -1
  60. package/dist/templates/spa/vitest.config.ts +0 -4
  61. package/dist/templates/ssg/README.md +1 -1
  62. package/dist/templates/ssg/package.json +1 -1
  63. package/dist/templates/ssg/ssg.config.ts +7 -0
  64. package/dist/templates/ssg/tests/ssg-config.test.ts +5 -3
  65. package/dist/templates/ssg/tsconfig.json +2 -1
  66. package/dist/templates/ssg/vitest.config.ts +0 -4
  67. package/dist/templates/ssr/package.json +2 -2
  68. package/dist/templates/ssr/server.ts +4 -10
  69. package/dist/templates/ssr/src/entry-server.tsx +6 -4
  70. package/dist/templates/startkit/package.json +2 -2
  71. package/dist/templates/startkit/src/lib/mock-data.ts +17 -39
  72. package/dist/templates/startkit/tsconfig.json +2 -1
  73. package/dist/update.d.ts +41 -0
  74. package/dist/update.js +282 -2
  75. package/dist/writer-D8qe_7ud.js +226 -0
  76. package/package.json +23 -22
  77. package/dist/add-DqhqRzBQ.js +0 -555
  78. package/dist/add-DqhqRzBQ.js.map +0 -1
  79. package/dist/cli.js.map +0 -1
  80. package/dist/create.js.map +0 -1
  81. package/dist/is-direct-execution-Cdlr-ZUl.js.map +0 -1
  82. package/dist/openapi.js.map +0 -1
  83. package/dist/skills-Bh0mEhIx.js.map +0 -1
  84. package/dist/ssg.js.map +0 -1
  85. package/dist/templates/full-stack/src/vite-server.d.ts +0 -6
  86. package/dist/templates/spa/src/styles.d.ts +0 -1
  87. package/dist/templates/ssg/src/vite-env.d.ts +0 -5
  88. package/dist/templates/ssr/src/vite-server.d.ts +0 -7
  89. package/dist/templates/startkit/src/vite-env.d.ts +0 -5
  90. package/dist/update-DyW1na5V.js +0 -1140
  91. package/dist/update-DyW1na5V.js.map +0 -1
  92. package/skills/askr-accessibility/SKILL.md +0 -68
  93. package/skills/askr-accessibility/agents/openai.yaml +0 -4
  94. package/skills/askr-agent-execution/SKILL.md +0 -85
  95. package/skills/askr-agent-execution/agents/openai.yaml +0 -4
  96. package/skills/askr-agent-workflows/SKILL.md +0 -57
  97. package/skills/askr-agent-workflows/agents/openai.yaml +0 -4
  98. package/skills/askr-api-integration/SKILL.md +0 -79
  99. package/skills/askr-api-integration/agents/openai.yaml +0 -4
  100. package/skills/askr-app-builder/SKILL.md +0 -99
  101. package/skills/askr-app-builder/agents/openai.yaml +0 -4
  102. package/skills/askr-auth-access/SKILL.md +0 -74
  103. package/skills/askr-auth-access/agents/openai.yaml +0 -4
  104. package/skills/askr-cli-vite/SKILL.md +0 -76
  105. package/skills/askr-cli-vite/agents/openai.yaml +0 -4
  106. package/skills/askr-dashboard-charts/SKILL.md +0 -82
  107. package/skills/askr-dashboard-charts/agents/openai.yaml +0 -4
  108. package/skills/askr-design-system/SKILL.md +0 -86
  109. package/skills/askr-design-system/agents/openai.yaml +0 -4
  110. package/skills/askr-env-config/SKILL.md +0 -74
  111. package/skills/askr-env-config/agents/openai.yaml +0 -4
  112. package/skills/askr-error-loading-empty/SKILL.md +0 -89
  113. package/skills/askr-error-loading-empty/agents/openai.yaml +0 -4
  114. package/skills/askr-file-upload-artifacts/SKILL.md +0 -77
  115. package/skills/askr-file-upload-artifacts/agents/openai.yaml +0 -4
  116. package/skills/askr-forms-tables-crud/SKILL.md +0 -98
  117. package/skills/askr-forms-tables-crud/agents/openai.yaml +0 -4
  118. package/skills/askr-mental-model/SKILL.md +0 -109
  119. package/skills/askr-mental-model/agents/openai.yaml +0 -4
  120. package/skills/askr-migration-react/SKILL.md +0 -81
  121. package/skills/askr-migration-react/agents/openai.yaml +0 -4
  122. package/skills/askr-observability-debugging/SKILL.md +0 -83
  123. package/skills/askr-observability-debugging/agents/openai.yaml +0 -4
  124. package/skills/askr-project-structure/SKILL.md +0 -79
  125. package/skills/askr-project-structure/agents/openai.yaml +0 -4
  126. package/skills/askr-query-mutation/SKILL.md +0 -115
  127. package/skills/askr-query-mutation/agents/openai.yaml +0 -4
  128. package/skills/askr-realtime-streaming/SKILL.md +0 -76
  129. package/skills/askr-realtime-streaming/agents/openai.yaml +0 -4
  130. package/skills/askr-resources-data/SKILL.md +0 -100
  131. package/skills/askr-resources-data/agents/openai.yaml +0 -4
  132. package/skills/askr-routing-layouts/SKILL.md +0 -107
  133. package/skills/askr-routing-layouts/agents/openai.yaml +0 -4
  134. package/skills/askr-runtime-reactivity/SKILL.md +0 -92
  135. package/skills/askr-runtime-reactivity/agents/openai.yaml +0 -4
  136. package/skills/askr-ssr-ssg/SKILL.md +0 -76
  137. package/skills/askr-ssr-ssg/agents/openai.yaml +0 -4
  138. package/skills/askr-testing-determinism/SKILL.md +0 -75
  139. package/skills/askr-testing-determinism/agents/openai.yaml +0 -4
  140. package/skills/askr-theming/SKILL.md +0 -86
  141. package/skills/askr-theming/agents/openai.yaml +0 -4
  142. package/skills/askr-ui-composition/SKILL.md +0 -92
  143. package/skills/askr-ui-composition/agents/openai.yaml +0 -4
  144. package/templates/full-stack/AGENTS.md +0 -12
  145. package/templates/full-stack/README.md +0 -18
  146. package/templates/full-stack/gitignore.template +0 -4
  147. package/templates/full-stack/index.html +0 -14
  148. package/templates/full-stack/package.json +0 -37
  149. package/templates/full-stack/server.ts +0 -13
  150. package/templates/full-stack/src/action-authorizations.ts +0 -10
  151. package/templates/full-stack/src/actions/create-message.ts +0 -10
  152. package/templates/full-stack/src/i18n.ts +0 -8
  153. package/templates/full-stack/src/main.tsx +0 -12
  154. package/templates/full-stack/src/pages/home.tsx +0 -25
  155. package/templates/full-stack/src/pages/layout.tsx +0 -33
  156. package/templates/full-stack/src/pages/not-found.tsx +0 -4
  157. package/templates/full-stack/src/routes.tsx +0 -20
  158. package/templates/full-stack/src/schemas.ts +0 -11
  159. package/templates/full-stack/src/server/action-registry.ts +0 -12
  160. package/templates/full-stack/src/server/actions/create-message.ts +0 -14
  161. package/templates/full-stack/src/server/app.ts +0 -66
  162. package/templates/full-stack/src/server/dependencies.ts +0 -55
  163. package/templates/full-stack/src/server/entry-server.ts +0 -8
  164. package/templates/full-stack/src/telemetry.ts +0 -4
  165. package/templates/full-stack/src/vite-server.d.ts +0 -6
  166. package/templates/full-stack/tests/actions/create-message.test.ts +0 -13
  167. package/templates/full-stack/tsconfig.json +0 -16
  168. package/templates/full-stack/vite.config.ts +0 -11
  169. package/templates/spa/AGENTS.md +0 -60
  170. package/templates/spa/README.md +0 -96
  171. package/templates/spa/gitignore.template +0 -16
  172. package/templates/spa/index.html +0 -13
  173. package/templates/spa/package.json +0 -35
  174. package/templates/spa/src/adapters/operations-client.ts +0 -90
  175. package/templates/spa/src/components/shared/metric-card.tsx +0 -27
  176. package/templates/spa/src/components/shared/status-badge.tsx +0 -24
  177. package/templates/spa/src/features/operations/operations.query.ts +0 -9
  178. package/templates/spa/src/main.tsx +0 -10
  179. package/templates/spa/src/pages/_layout.tsx +0 -9
  180. package/templates/spa/src/pages/_routes.tsx +0 -27
  181. package/templates/spa/src/pages/app/_layout.tsx +0 -94
  182. package/templates/spa/src/pages/app/_routes.tsx +0 -10
  183. package/templates/spa/src/pages/app/admin-home.tsx +0 -152
  184. package/templates/spa/src/pages/app/agent-runs.tsx +0 -93
  185. package/templates/spa/src/pages/app/settings.tsx +0 -91
  186. package/templates/spa/src/pages/auth/_layout.tsx +0 -38
  187. package/templates/spa/src/pages/auth/_routes.tsx +0 -6
  188. package/templates/spa/src/pages/auth/login.tsx +0 -63
  189. package/templates/spa/src/pages/not-found.tsx +0 -22
  190. package/templates/spa/src/pages/public/_layout.tsx +0 -47
  191. package/templates/spa/src/pages/public/_routes.tsx +0 -6
  192. package/templates/spa/src/pages/public/home.tsx +0 -143
  193. package/templates/spa/src/shared/format.ts +0 -12
  194. package/templates/spa/src/shared/navigation.ts +0 -15
  195. package/templates/spa/src/styles/components.css +0 -49
  196. package/templates/spa/src/styles/layout.css +0 -192
  197. package/templates/spa/src/styles/reset.css +0 -44
  198. package/templates/spa/src/styles/theme.css +0 -57
  199. package/templates/spa/src/styles/tokens.css +0 -20
  200. package/templates/spa/src/styles.css +0 -7
  201. package/templates/spa/src/styles.d.ts +0 -1
  202. package/templates/spa/tests/app.test.tsx +0 -37
  203. package/templates/spa/tests/components/shared.test.tsx +0 -12
  204. package/templates/spa/tests/resources.test.ts +0 -22
  205. package/templates/spa/tsconfig.json +0 -20
  206. package/templates/spa/tsconfig.node.json +0 -10
  207. package/templates/spa/vite.config.ts +0 -24
  208. package/templates/spa/vitest.config.ts +0 -17
  209. package/templates/ssg/AGENTS.md +0 -55
  210. package/templates/ssg/README.md +0 -39
  211. package/templates/ssg/gitignore.template +0 -17
  212. package/templates/ssg/index.html +0 -13
  213. package/templates/ssg/package.json +0 -35
  214. package/templates/ssg/src/app.tsx +0 -14
  215. package/templates/ssg/src/components/badge.tsx +0 -3
  216. package/templates/ssg/src/components/counter.tsx +0 -30
  217. package/templates/ssg/src/components/site-shell.tsx +0 -111
  218. package/templates/ssg/src/jsx.d.ts +0 -23
  219. package/templates/ssg/src/main.tsx +0 -8
  220. package/templates/ssg/src/pages/about.tsx +0 -82
  221. package/templates/ssg/src/pages/content.tsx +0 -63
  222. package/templates/ssg/src/pages/example.tsx +0 -97
  223. package/templates/ssg/src/pages/home.tsx +0 -51
  224. package/templates/ssg/src/resources/user.ts +0 -15
  225. package/templates/ssg/src/routes.tsx +0 -15
  226. package/templates/ssg/src/styles.css +0 -89
  227. package/templates/ssg/src/vite-env.d.ts +0 -5
  228. package/templates/ssg/ssg.config.ts +0 -34
  229. package/templates/ssg/tests/app.test.tsx +0 -19
  230. package/templates/ssg/tests/components/counter.test.tsx +0 -18
  231. package/templates/ssg/tests/resources.test.ts +0 -11
  232. package/templates/ssg/tests/ssg-config.test.ts +0 -11
  233. package/templates/ssg/tsconfig.json +0 -20
  234. package/templates/ssg/tsconfig.node.json +0 -10
  235. package/templates/ssg/vite.config.ts +0 -24
  236. package/templates/ssg/vitest.config.ts +0 -17
  237. package/templates/ssr/AGENTS.md +0 -28
  238. package/templates/ssr/README.md +0 -38
  239. package/templates/ssr/gitignore.template +0 -16
  240. package/templates/ssr/index.html +0 -13
  241. package/templates/ssr/package.json +0 -34
  242. package/templates/ssr/server.ts +0 -16
  243. package/templates/ssr/src/app.tsx +0 -21
  244. package/templates/ssr/src/components/counter.tsx +0 -26
  245. package/templates/ssr/src/entry-server.tsx +0 -10
  246. package/templates/ssr/src/main.tsx +0 -11
  247. package/templates/ssr/src/pages/about.tsx +0 -75
  248. package/templates/ssr/src/pages/example.tsx +0 -113
  249. package/templates/ssr/src/pages/home.tsx +0 -56
  250. package/templates/ssr/src/resources/user.ts +0 -15
  251. package/templates/ssr/src/routes.tsx +0 -13
  252. package/templates/ssr/src/styles.css +0 -148
  253. package/templates/ssr/src/vite-server.d.ts +0 -7
  254. package/templates/ssr/tests/app.test.tsx +0 -24
  255. package/templates/ssr/tests/components/counter.test.tsx +0 -13
  256. package/templates/ssr/tests/resources.test.ts +0 -11
  257. package/templates/ssr/tsconfig.json +0 -22
  258. package/templates/ssr/tsconfig.node.json +0 -10
  259. package/templates/ssr/tsconfig.server.json +0 -15
  260. package/templates/ssr/vite.config.ts +0 -25
  261. package/templates/ssr/vitest.config.ts +0 -13
  262. package/templates/startkit/AGENTS.md +0 -77
  263. package/templates/startkit/README.md +0 -192
  264. package/templates/startkit/gitignore.template +0 -16
  265. package/templates/startkit/index.html +0 -13
  266. package/templates/startkit/package.json +0 -35
  267. package/templates/startkit/src/components/app-header.tsx +0 -93
  268. package/templates/startkit/src/components/app-sidebar.tsx +0 -95
  269. package/templates/startkit/src/components/data-table.tsx +0 -80
  270. package/templates/startkit/src/components/empty-state.tsx +0 -13
  271. package/templates/startkit/src/components/page-header.tsx +0 -23
  272. package/templates/startkit/src/components/stat-card.tsx +0 -24
  273. package/templates/startkit/src/features/accounts/account-filters.tsx +0 -61
  274. package/templates/startkit/src/features/accounts/account-table.tsx +0 -79
  275. package/templates/startkit/src/lib/format.ts +0 -31
  276. package/templates/startkit/src/lib/mock-data.ts +0 -441
  277. package/templates/startkit/src/lib/routes.ts +0 -116
  278. package/templates/startkit/src/main.tsx +0 -12
  279. package/templates/startkit/src/pages/_layout.tsx +0 -56
  280. package/templates/startkit/src/pages/auth/_layout.tsx +0 -7
  281. package/templates/startkit/src/pages/auth/login.tsx +0 -129
  282. package/templates/startkit/src/pages/home.tsx +0 -83
  283. package/templates/startkit/src/pages/not-found.tsx +0 -24
  284. package/templates/startkit/src/pages/workspace/_layout.tsx +0 -17
  285. package/templates/startkit/src/pages/workspace/accounts/index.tsx +0 -217
  286. package/templates/startkit/src/pages/workspace/dashboard.tsx +0 -118
  287. package/templates/startkit/src/pages/workspace/settings.tsx +0 -218
  288. package/templates/startkit/src/router.tsx +0 -7
  289. package/templates/startkit/src/routes/auth-config.ts +0 -38
  290. package/templates/startkit/src/routes/auth.ts +0 -8
  291. package/templates/startkit/src/routes/index.ts +0 -28
  292. package/templates/startkit/src/routes/public.ts +0 -8
  293. package/templates/startkit/src/routes/workspace/accounts.ts +0 -8
  294. package/templates/startkit/src/routes/workspace/index.ts +0 -14
  295. package/templates/startkit/src/styles/components.css +0 -396
  296. package/templates/startkit/src/styles/layout.css +0 -192
  297. package/templates/startkit/src/styles/reset.css +0 -38
  298. package/templates/startkit/src/styles/theme.css +0 -76
  299. package/templates/startkit/src/styles/tokens.css +0 -67
  300. package/templates/startkit/src/styles.css +0 -7
  301. package/templates/startkit/src/toast.ts +0 -55
  302. package/templates/startkit/src/utils/join-classes.ts +0 -4
  303. package/templates/startkit/src/vite-env.d.ts +0 -5
  304. package/templates/startkit/tests/app.test.tsx +0 -32
  305. package/templates/startkit/tests/preferences.test.ts +0 -43
  306. package/templates/startkit/tests/resources.test.ts +0 -82
  307. package/templates/startkit/tsconfig.json +0 -20
  308. package/templates/startkit/tsconfig.node.json +0 -10
  309. package/templates/startkit/vite.config.ts +0 -32
  310. package/templates/startkit/vitest.config.ts +0 -13
@@ -0,0 +1,323 @@
1
+ import { t as analyzeRange } from "./range-YUs9eimn.js";
2
+ import { t as parseDependencySpecification } from "./specification-DXnDOC-0.js";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { load } from "js-yaml";
6
+ import { minimatch } from "minimatch";
7
+ //#region src/update/types.ts
8
+ const DEPENDENCY_SECTIONS = [
9
+ "dependencies",
10
+ "devDependencies",
11
+ "optionalDependencies",
12
+ "peerDependencies"
13
+ ];
14
+ //#endregion
15
+ //#region src/update/discovery.ts
16
+ async function isFile(filePath) {
17
+ return (await fs.stat(filePath).catch(() => null))?.isFile() ?? false;
18
+ }
19
+ async function readManifest(manifestPath) {
20
+ let source;
21
+ try {
22
+ source = await fs.readFile(manifestPath, "utf8");
23
+ } catch {
24
+ throw new Error(`Unable to read manifest: ${manifestPath}`);
25
+ }
26
+ try {
27
+ const value = JSON.parse(source.replace(/^\uFEFF/, ""));
28
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error();
29
+ return value;
30
+ } catch {
31
+ throw new Error(`Malformed package manifest: ${manifestPath}`);
32
+ }
33
+ }
34
+ function packageWorkspacePatterns(manifest) {
35
+ if (!("workspaces" in manifest)) return null;
36
+ const declaration = manifest.workspaces;
37
+ const patterns = Array.isArray(declaration) ? declaration : declaration && typeof declaration === "object" && !Array.isArray(declaration) ? declaration.packages : null;
38
+ if (!Array.isArray(patterns) || patterns.some((pattern) => typeof pattern !== "string")) throw new Error("Invalid package.json workspaces declaration; expected an array of paths.");
39
+ return patterns;
40
+ }
41
+ async function pnpmWorkspacePatterns(root) {
42
+ const workspacePath = path.join(root, "pnpm-workspace.yaml");
43
+ if (!await isFile(workspacePath)) return null;
44
+ const source = await fs.readFile(workspacePath, "utf8");
45
+ let value;
46
+ try {
47
+ value = load(source);
48
+ } catch {
49
+ throw new Error(`Malformed pnpm workspace declaration: ${workspacePath}`);
50
+ }
51
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid pnpm workspace declaration; expected a mapping with packages.");
52
+ const packages = value.packages;
53
+ if (!Array.isArray(packages) || packages.some((pattern) => typeof pattern !== "string")) throw new Error("Invalid pnpm workspace declaration; expected packages to be an array.");
54
+ return packages;
55
+ }
56
+ async function findProjectRoot(start) {
57
+ const resolved = path.resolve(start);
58
+ if (!(await fs.stat(resolved).catch(() => null))?.isDirectory()) throw new Error(`Working directory does not exist: ${resolved}`);
59
+ let directory = resolved;
60
+ let nearestManifestDirectory = null;
61
+ while (true) {
62
+ const manifestPath = path.join(directory, "package.json");
63
+ const hasManifest = await isFile(manifestPath);
64
+ if (hasManifest) {
65
+ const manifest = await readManifest(manifestPath);
66
+ nearestManifestDirectory ??= directory;
67
+ if (packageWorkspacePatterns(manifest) !== null) return directory;
68
+ }
69
+ if (await isFile(path.join(directory, "pnpm-workspace.yaml"))) {
70
+ if (!hasManifest) throw new Error(`Workspace root is missing package.json: ${directory}`);
71
+ await pnpmWorkspacePatterns(directory);
72
+ return directory;
73
+ }
74
+ const parent = path.dirname(directory);
75
+ if (parent === directory) break;
76
+ directory = parent;
77
+ }
78
+ if (nearestManifestDirectory) return nearestManifestDirectory;
79
+ throw new Error(`No package.json found from ${resolved}.`);
80
+ }
81
+ function parsePolicy(manifest) {
82
+ const empty = {
83
+ ignore: [],
84
+ tags: {}
85
+ };
86
+ if (!("askr" in manifest)) return empty;
87
+ if (!manifest.askr || typeof manifest.askr !== "object" || Array.isArray(manifest.askr)) throw new Error("Invalid askr update configuration in the workspace root.");
88
+ const update = manifest.askr.update;
89
+ if (update === void 0) return empty;
90
+ if (!update || typeof update !== "object" || Array.isArray(update)) throw new Error("Invalid askr.update configuration in the workspace root.");
91
+ const config = update;
92
+ const ignore = config.ignore ?? [];
93
+ const tags = config.tags ?? {};
94
+ if (!Array.isArray(ignore) || ignore.some((entry) => typeof entry !== "string")) throw new Error("Invalid askr.update.ignore configuration; expected an array of patterns.");
95
+ if (!tags || typeof tags !== "object" || Array.isArray(tags) || Object.entries(tags).some(([name, tag]) => !name || typeof tag !== "string" || !tag)) throw new Error("Invalid askr.update.tags configuration; expected package-to-tag strings.");
96
+ return {
97
+ ignore,
98
+ tags
99
+ };
100
+ }
101
+ function relativeManifestPath(root, manifestPath) {
102
+ return path.relative(root, manifestPath).split(path.sep).join("/") || "package.json";
103
+ }
104
+ function workspaceName(manifest, fallback) {
105
+ return typeof manifest.name === "string" && manifest.name.trim() ? manifest.name : fallback;
106
+ }
107
+ const WORKSPACE_GLOB_OPTIONS = {
108
+ dot: true,
109
+ nocase: process.platform === "win32",
110
+ windowsPathsNoEscape: true
111
+ };
112
+ function normalizeWorkspacePattern(pattern) {
113
+ const leadingBangs = pattern.match(/^!+/)?.[0].length ?? 0;
114
+ const negative = leadingBangs % 2 === 1;
115
+ let value = pattern.slice(leadingBangs);
116
+ value = value.replace(/\\/g, "/").replace(/^\.\//, "").replace(/^\/+/, "").replace(/\/+$/, "");
117
+ if (value.endsWith("/package.json")) value = value.slice(0, -13);
118
+ if (value === ".." || value.startsWith("../")) throw new Error(`Workspace patterns outside the project root are unsupported: ${pattern}`);
119
+ return {
120
+ negative,
121
+ value: value || "."
122
+ };
123
+ }
124
+ function matchesWorkspace(relativeDirectory, patterns) {
125
+ let included = false;
126
+ for (const pattern of patterns) {
127
+ const normalized = normalizeWorkspacePattern(pattern);
128
+ if (minimatch(relativeDirectory, normalized.value, WORKSPACE_GLOB_OPTIONS)) included = !normalized.negative;
129
+ }
130
+ return included;
131
+ }
132
+ function mayContainWorkspace(relativeDirectory, patterns) {
133
+ return patterns.some((pattern) => {
134
+ const normalized = normalizeWorkspacePattern(pattern);
135
+ return !normalized.negative && minimatch(relativeDirectory, normalized.value, {
136
+ ...WORKSPACE_GLOB_OPTIONS,
137
+ partial: true
138
+ });
139
+ });
140
+ }
141
+ async function mapDeclaredWorkspaces(root, patterns) {
142
+ const directories = [];
143
+ if (matchesWorkspace(".", patterns)) directories.push(root);
144
+ const visit = async (directory, relativeDirectory) => {
145
+ const entries = await fs.readdir(directory, { withFileTypes: true });
146
+ entries.sort((left, right) => left.name.localeCompare(right.name));
147
+ for (const entry of entries) {
148
+ if (entry.name === "node_modules" || entry.name === ".git") continue;
149
+ const childRelative = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
150
+ if (!mayContainWorkspace(childRelative, patterns)) continue;
151
+ const child = path.join(directory, entry.name);
152
+ const isSymbolicDirectory = entry.isSymbolicLink() && (await fs.stat(child).catch(() => null))?.isDirectory();
153
+ if (!entry.isDirectory() && !isSymbolicDirectory) continue;
154
+ if (matchesWorkspace(childRelative, patterns) && await isFile(path.join(child, "package.json"))) directories.push(child);
155
+ if (!entry.isSymbolicLink()) await visit(child, childRelative);
156
+ }
157
+ };
158
+ await visit(root, "");
159
+ const mapped = /* @__PURE__ */ new Map();
160
+ for (const directory of directories.sort((left, right) => left.localeCompare(right))) {
161
+ const name = workspaceName(await readManifest(path.join(directory, "package.json")), path.basename(directory));
162
+ if (mapped.has(name)) throw new Error(`Multiple workspaces with the same name '${name}'.`);
163
+ mapped.set(name, directory);
164
+ }
165
+ return mapped;
166
+ }
167
+ async function discoverWorkspaces(root) {
168
+ const rootManifestPath = path.join(root, "package.json");
169
+ const rootManifest = await readManifest(rootManifestPath);
170
+ const policy = parsePolicy(rootManifest);
171
+ const packagePatterns = packageWorkspacePatterns(rootManifest) ?? [];
172
+ const pnpmPatterns = await pnpmWorkspacePatterns(root) ?? [];
173
+ const patterns = [...packagePatterns, ...pnpmPatterns];
174
+ const mapped = patterns.length > 0 ? await mapDeclaredWorkspaces(root, patterns) : /* @__PURE__ */ new Map();
175
+ const rootName = workspaceName(rootManifest, "(root)");
176
+ if (mapped.has(rootName)) throw new Error(`Duplicate workspace name '${rootName}' includes the workspace root.`);
177
+ const workspaces = [{
178
+ name: rootName,
179
+ directory: root,
180
+ manifestPath: rootManifestPath,
181
+ relativeManifestPath: "package.json",
182
+ manifest: rootManifest,
183
+ isRoot: true
184
+ }];
185
+ for (const [mappedName, directory] of mapped) {
186
+ const manifestPath = path.join(directory, "package.json");
187
+ const manifest = await readManifest(manifestPath);
188
+ workspaces.push({
189
+ name: workspaceName(manifest, mappedName),
190
+ directory,
191
+ manifestPath,
192
+ relativeManifestPath: relativeManifestPath(root, manifestPath),
193
+ manifest,
194
+ isRoot: false
195
+ });
196
+ }
197
+ workspaces.sort((left, right) => {
198
+ if (left.isRoot !== right.isRoot) return left.isRoot ? -1 : 1;
199
+ return left.name.localeCompare(right.name) || left.manifestPath.localeCompare(right.manifestPath);
200
+ });
201
+ return {
202
+ policy,
203
+ rootManifest,
204
+ workspaces
205
+ };
206
+ }
207
+ function matchesAny(value, patterns) {
208
+ return patterns.some((pattern) => minimatch(value, pattern, { dot: true }));
209
+ }
210
+ function isRegistryPackageName(packageName) {
211
+ if (!packageName || packageName.length > 214 || /^[._-]/.test(packageName) || /[\s%\\:]/.test(packageName)) return false;
212
+ if (!packageName.startsWith("@")) return !packageName.includes("/");
213
+ const parts = packageName.slice(1).split("/");
214
+ return parts.length === 2 && parts.every((part) => part.length > 0 && !/^[._-]/.test(part));
215
+ }
216
+ function classifySpecification(packageName, specification, directory, localNames) {
217
+ if (localNames.has(packageName)) return {
218
+ kind: "local",
219
+ registryManaged: false,
220
+ reason: "dependency resolves to a discovered workspace"
221
+ };
222
+ if (/^workspace:/i.test(specification)) return {
223
+ kind: "local",
224
+ registryManaged: false,
225
+ reason: "workspace protocol is not registry-managed"
226
+ };
227
+ if (/^link:/i.test(specification)) return {
228
+ kind: "local",
229
+ registryManaged: false,
230
+ reason: "link protocol is not registry-managed"
231
+ };
232
+ if (!isRegistryPackageName(packageName)) return {
233
+ kind: "manual",
234
+ registryManaged: false,
235
+ reason: "invalid registry package name"
236
+ };
237
+ const parsed = parseDependencySpecification(specification);
238
+ if ([
239
+ "file",
240
+ "git",
241
+ "remote"
242
+ ].includes(parsed.type)) return {
243
+ kind: "local",
244
+ registryManaged: false,
245
+ reason: `${parsed.type} specification is not registry-managed`
246
+ };
247
+ if (parsed.type === "alias") return {
248
+ kind: "manual",
249
+ registryManaged: false,
250
+ reason: "npm aliases require manual review"
251
+ };
252
+ if (parsed.type === "tag") return {
253
+ kind: "current",
254
+ registryManaged: true,
255
+ reason: "tracking tag is not rewritten"
256
+ };
257
+ if (parsed.type !== "range" && parsed.type !== "version") return {
258
+ kind: "manual",
259
+ registryManaged: false,
260
+ reason: "unsupported dependency specification"
261
+ };
262
+ const analysis = analyzeRange(specification);
263
+ if (analysis.tracking) return {
264
+ kind: "current",
265
+ registryManaged: true,
266
+ reason: analysis.reason
267
+ };
268
+ if (!analysis.shape) return {
269
+ kind: "manual",
270
+ registryManaged: false,
271
+ reason: analysis.reason
272
+ };
273
+ return {
274
+ kind: "fetch",
275
+ registryManaged: true,
276
+ reason: ""
277
+ };
278
+ }
279
+ function collectOccurrences(root, workspaces, localNames, policy, packagePatterns) {
280
+ const occurrences = [];
281
+ for (const workspace of workspaces) for (const section of DEPENDENCY_SECTIONS) {
282
+ const dependencies = workspace.manifest[section];
283
+ if (dependencies === void 0) continue;
284
+ if (!dependencies || typeof dependencies !== "object" || Array.isArray(dependencies)) throw new Error(`Invalid ${section} in ${workspace.relativeManifestPath}; expected an object.`);
285
+ for (const [packageName, specification] of Object.entries(dependencies)) {
286
+ if (typeof specification !== "string") throw new Error(`Invalid ${section}.${packageName} in ${workspace.relativeManifestPath}.`);
287
+ if (packagePatterns.length > 0 && !matchesAny(packageName, packagePatterns)) continue;
288
+ if (packagePatterns.length === 0 && matchesAny(packageName, policy.ignore)) continue;
289
+ occurrences.push({
290
+ package: packageName,
291
+ workspace: workspace.name,
292
+ manifestPath: workspace.manifestPath,
293
+ relativeManifestPath: relativeManifestPath(root, workspace.manifestPath),
294
+ section,
295
+ currentSpecification: specification,
296
+ ...classifySpecification(packageName, specification, workspace.directory, localNames)
297
+ });
298
+ }
299
+ }
300
+ const sectionOrder = new Map(DEPENDENCY_SECTIONS.map((section, index) => [section, index]));
301
+ occurrences.sort((left, right) => left.package.localeCompare(right.package) || left.workspace.localeCompare(right.workspace) || left.relativeManifestPath.localeCompare(right.relativeManifestPath) || sectionOrder.get(left.section) - sectionOrder.get(right.section));
302
+ return occurrences;
303
+ }
304
+ async function discoverProject(options) {
305
+ const root = await findProjectRoot(options.cwd);
306
+ const { policy, workspaces } = await discoverWorkspaces(root);
307
+ const selectedWorkspaces = options.workspacePatterns.length === 0 ? workspaces : workspaces.filter((workspace) => matchesAny(workspace.name, options.workspacePatterns));
308
+ if (selectedWorkspaces.length === 0) throw new Error("No discovered workspace matches the requested --workspace filters.");
309
+ const localNames = new Set(workspaces.map((workspace) => workspace.name));
310
+ return {
311
+ root,
312
+ workspaces,
313
+ selectedWorkspaces,
314
+ policy,
315
+ occurrences: collectOccurrences(root, selectedWorkspaces, localNames, policy, options.packagePatterns),
316
+ contextOccurrences: collectOccurrences(root, selectedWorkspaces, localNames, {
317
+ ignore: [],
318
+ tags: policy.tags
319
+ }, [])
320
+ };
321
+ }
322
+ //#endregion
323
+ export { discoverProject };
@@ -0,0 +1,5 @@
1
+ //#region src/bin/generate.d.ts
2
+ type Io = Pick<Console, "error" | "log">;
3
+ declare function runGenerateCli(args: string[], io?: Io): Promise<number>;
4
+ //#endregion
5
+ export { runGenerateCli };