@mcp-rune/create 0.11.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 (242) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -0
  3. package/bin/rune.js +7 -0
  4. package/dist/commands/add-model.d.ts +5 -0
  5. package/dist/commands/add-model.d.ts.map +1 -0
  6. package/dist/commands/add-model.js +131 -0
  7. package/dist/commands/add-model.js.map +1 -0
  8. package/dist/commands/db-up.d.ts +2 -0
  9. package/dist/commands/db-up.d.ts.map +1 -0
  10. package/dist/commands/db-up.js +29 -0
  11. package/dist/commands/db-up.js.map +1 -0
  12. package/dist/commands/doctor/env-checks.d.ts +4 -0
  13. package/dist/commands/doctor/env-checks.d.ts.map +1 -0
  14. package/dist/commands/doctor/env-checks.js +88 -0
  15. package/dist/commands/doctor/env-checks.js.map +1 -0
  16. package/dist/commands/doctor/index.d.ts +21 -0
  17. package/dist/commands/doctor/index.d.ts.map +1 -0
  18. package/dist/commands/doctor/index.js +44 -0
  19. package/dist/commands/doctor/index.js.map +1 -0
  20. package/dist/commands/doctor/project-validation.d.ts +5 -0
  21. package/dist/commands/doctor/project-validation.d.ts.map +1 -0
  22. package/dist/commands/doctor/project-validation.js +166 -0
  23. package/dist/commands/doctor/project-validation.js.map +1 -0
  24. package/dist/commands/doctor.d.ts +7 -0
  25. package/dist/commands/doctor.d.ts.map +1 -0
  26. package/dist/commands/doctor.js +306 -0
  27. package/dist/commands/doctor.js.map +1 -0
  28. package/dist/commands/inspect.d.ts +16 -0
  29. package/dist/commands/inspect.d.ts.map +1 -0
  30. package/dist/commands/inspect.js +66 -0
  31. package/dist/commands/inspect.js.map +1 -0
  32. package/dist/commands/new/actions/apps.d.ts +5 -0
  33. package/dist/commands/new/actions/apps.d.ts.map +1 -0
  34. package/dist/commands/new/actions/apps.js +51 -0
  35. package/dist/commands/new/actions/apps.js.map +1 -0
  36. package/dist/commands/new/actions/architecture.d.ts +5 -0
  37. package/dist/commands/new/actions/architecture.d.ts.map +1 -0
  38. package/dist/commands/new/actions/architecture.js +45 -0
  39. package/dist/commands/new/actions/architecture.js.map +1 -0
  40. package/dist/commands/new/actions/auth.d.ts +5 -0
  41. package/dist/commands/new/actions/auth.d.ts.map +1 -0
  42. package/dist/commands/new/actions/auth.js +30 -0
  43. package/dist/commands/new/actions/auth.js.map +1 -0
  44. package/dist/commands/new/actions/database.d.ts +5 -0
  45. package/dist/commands/new/actions/database.d.ts.map +1 -0
  46. package/dist/commands/new/actions/database.js +60 -0
  47. package/dist/commands/new/actions/database.js.map +1 -0
  48. package/dist/commands/new/actions/fetch-template.d.ts +5 -0
  49. package/dist/commands/new/actions/fetch-template.d.ts.map +1 -0
  50. package/dist/commands/new/actions/fetch-template.js +22 -0
  51. package/dist/commands/new/actions/fetch-template.js.map +1 -0
  52. package/dist/commands/new/actions/intro.d.ts +5 -0
  53. package/dist/commands/new/actions/intro.d.ts.map +1 -0
  54. package/dist/commands/new/actions/intro.js +7 -0
  55. package/dist/commands/new/actions/intro.js.map +1 -0
  56. package/dist/commands/new/actions/layers.d.ts +5 -0
  57. package/dist/commands/new/actions/layers.d.ts.map +1 -0
  58. package/dist/commands/new/actions/layers.js +38 -0
  59. package/dist/commands/new/actions/layers.js.map +1 -0
  60. package/dist/commands/new/actions/models.d.ts +5 -0
  61. package/dist/commands/new/actions/models.d.ts.map +1 -0
  62. package/dist/commands/new/actions/models.js +18 -0
  63. package/dist/commands/new/actions/models.js.map +1 -0
  64. package/dist/commands/new/actions/next-steps.d.ts +5 -0
  65. package/dist/commands/new/actions/next-steps.d.ts.map +1 -0
  66. package/dist/commands/new/actions/next-steps.js +38 -0
  67. package/dist/commands/new/actions/next-steps.js.map +1 -0
  68. package/dist/commands/new/actions/observability.d.ts +5 -0
  69. package/dist/commands/new/actions/observability.d.ts.map +1 -0
  70. package/dist/commands/new/actions/observability.js +45 -0
  71. package/dist/commands/new/actions/observability.js.map +1 -0
  72. package/dist/commands/new/actions/post-scaffold.d.ts +5 -0
  73. package/dist/commands/new/actions/post-scaffold.d.ts.map +1 -0
  74. package/dist/commands/new/actions/post-scaffold.js +81 -0
  75. package/dist/commands/new/actions/post-scaffold.js.map +1 -0
  76. package/dist/commands/new/actions/preset.d.ts +5 -0
  77. package/dist/commands/new/actions/preset.d.ts.map +1 -0
  78. package/dist/commands/new/actions/preset.js +23 -0
  79. package/dist/commands/new/actions/preset.js.map +1 -0
  80. package/dist/commands/new/actions/prompts.d.ts +5 -0
  81. package/dist/commands/new/actions/prompts.d.ts.map +1 -0
  82. package/dist/commands/new/actions/prompts.js +33 -0
  83. package/dist/commands/new/actions/prompts.js.map +1 -0
  84. package/dist/commands/new/actions/render.d.ts +5 -0
  85. package/dist/commands/new/actions/render.d.ts.map +1 -0
  86. package/dist/commands/new/actions/render.js +35 -0
  87. package/dist/commands/new/actions/render.js.map +1 -0
  88. package/dist/commands/new/actions/scaffold-header.d.ts +5 -0
  89. package/dist/commands/new/actions/scaffold-header.d.ts.map +1 -0
  90. package/dist/commands/new/actions/scaffold-header.js +19 -0
  91. package/dist/commands/new/actions/scaffold-header.js.map +1 -0
  92. package/dist/commands/new/actions/scaffold-mode.d.ts +5 -0
  93. package/dist/commands/new/actions/scaffold-mode.d.ts.map +1 -0
  94. package/dist/commands/new/actions/scaffold-mode.js +49 -0
  95. package/dist/commands/new/actions/scaffold-mode.js.map +1 -0
  96. package/dist/commands/new/actions/summary.d.ts +5 -0
  97. package/dist/commands/new/actions/summary.d.ts.map +1 -0
  98. package/dist/commands/new/actions/summary.js +71 -0
  99. package/dist/commands/new/actions/summary.js.map +1 -0
  100. package/dist/commands/new/actions/toggles.d.ts +5 -0
  101. package/dist/commands/new/actions/toggles.d.ts.map +1 -0
  102. package/dist/commands/new/actions/toggles.js +25 -0
  103. package/dist/commands/new/actions/toggles.js.map +1 -0
  104. package/dist/commands/new/actions/tools.d.ts +5 -0
  105. package/dist/commands/new/actions/tools.d.ts.map +1 -0
  106. package/dist/commands/new/actions/tools.js +36 -0
  107. package/dist/commands/new/actions/tools.js.map +1 -0
  108. package/dist/commands/new/actions/transport.d.ts +5 -0
  109. package/dist/commands/new/actions/transport.d.ts.map +1 -0
  110. package/dist/commands/new/actions/transport.js +24 -0
  111. package/dist/commands/new/actions/transport.js.map +1 -0
  112. package/dist/commands/new/context.d.ts +76 -0
  113. package/dist/commands/new/context.d.ts.map +1 -0
  114. package/dist/commands/new/context.js +134 -0
  115. package/dist/commands/new/context.js.map +1 -0
  116. package/dist/commands/new/index.d.ts +5 -0
  117. package/dist/commands/new/index.d.ts.map +1 -0
  118. package/dist/commands/new/index.js +18 -0
  119. package/dist/commands/new/index.js.map +1 -0
  120. package/dist/commands/new/pipeline.d.ts +12 -0
  121. package/dist/commands/new/pipeline.d.ts.map +1 -0
  122. package/dist/commands/new/pipeline.js +67 -0
  123. package/dist/commands/new/pipeline.js.map +1 -0
  124. package/dist/commands/new/presets.d.ts +40 -0
  125. package/dist/commands/new/presets.d.ts.map +1 -0
  126. package/dist/commands/new/presets.js +91 -0
  127. package/dist/commands/new/presets.js.map +1 -0
  128. package/dist/commands/new.d.ts +24 -0
  129. package/dist/commands/new.d.ts.map +1 -0
  130. package/dist/commands/new.js +162 -0
  131. package/dist/commands/new.js.map +1 -0
  132. package/dist/commands/post-scaffold.d.ts +6 -0
  133. package/dist/commands/post-scaffold.d.ts.map +1 -0
  134. package/dist/commands/post-scaffold.js +24 -0
  135. package/dist/commands/post-scaffold.js.map +1 -0
  136. package/dist/core/cancel.d.ts +3 -0
  137. package/dist/core/cancel.d.ts.map +1 -0
  138. package/dist/core/cancel.js +17 -0
  139. package/dist/core/cancel.js.map +1 -0
  140. package/dist/core/color.d.ts +12 -0
  141. package/dist/core/color.d.ts.map +1 -0
  142. package/dist/core/color.js +14 -0
  143. package/dist/core/color.js.map +1 -0
  144. package/dist/core/db-setup.d.ts +13 -0
  145. package/dist/core/db-setup.d.ts.map +1 -0
  146. package/dist/core/db-setup.js +63 -0
  147. package/dist/core/db-setup.js.map +1 -0
  148. package/dist/core/fs-utils.d.ts +4 -0
  149. package/dist/core/fs-utils.d.ts.map +1 -0
  150. package/dist/core/fs-utils.js +31 -0
  151. package/dist/core/fs-utils.js.map +1 -0
  152. package/dist/core/output.d.ts +19 -0
  153. package/dist/core/output.d.ts.map +1 -0
  154. package/dist/core/output.js +42 -0
  155. package/dist/core/output.js.map +1 -0
  156. package/dist/core/prompts.d.ts +2 -0
  157. package/dist/core/prompts.d.ts.map +1 -0
  158. package/dist/core/prompts.js +2 -0
  159. package/dist/core/prompts.js.map +1 -0
  160. package/dist/core/tasks.d.ts +11 -0
  161. package/dist/core/tasks.d.ts.map +1 -0
  162. package/dist/core/tasks.js +28 -0
  163. package/dist/core/tasks.js.map +1 -0
  164. package/dist/data/mascot.d.ts +13 -0
  165. package/dist/data/mascot.d.ts.map +1 -0
  166. package/dist/data/mascot.js +80 -0
  167. package/dist/data/mascot.js.map +1 -0
  168. package/dist/index.d.ts +4 -0
  169. package/dist/index.d.ts.map +1 -0
  170. package/dist/index.js +68 -0
  171. package/dist/index.js.map +1 -0
  172. package/dist/render/copy-tree.d.ts +5 -0
  173. package/dist/render/copy-tree.d.ts.map +1 -0
  174. package/dist/render/copy-tree.js +146 -0
  175. package/dist/render/copy-tree.js.map +1 -0
  176. package/dist/render/fetch-template.d.ts +9 -0
  177. package/dist/render/fetch-template.d.ts.map +1 -0
  178. package/dist/render/fetch-template.js +113 -0
  179. package/dist/render/fetch-template.js.map +1 -0
  180. package/dist/render/model-gen.d.ts +3 -0
  181. package/dist/render/model-gen.d.ts.map +1 -0
  182. package/dist/render/model-gen.js +23 -0
  183. package/dist/render/model-gen.js.map +1 -0
  184. package/dist/templates/registry.d.ts +14 -0
  185. package/dist/templates/registry.d.ts.map +1 -0
  186. package/dist/templates/registry.js +34 -0
  187. package/dist/templates/registry.js.map +1 -0
  188. package/dist/types.d.ts +87 -0
  189. package/dist/types.d.ts.map +1 -0
  190. package/dist/types.js +8 -0
  191. package/dist/types.js.map +1 -0
  192. package/dist/wizard/presets.d.ts +35 -0
  193. package/dist/wizard/presets.d.ts.map +1 -0
  194. package/dist/wizard/presets.js +67 -0
  195. package/dist/wizard/presets.js.map +1 -0
  196. package/dist/wizard/questions.d.ts +11 -0
  197. package/dist/wizard/questions.d.ts.map +1 -0
  198. package/dist/wizard/questions.js +154 -0
  199. package/dist/wizard/questions.js.map +1 -0
  200. package/package.json +52 -0
  201. package/templates/advanced/.env.example.ejs +82 -0
  202. package/templates/advanced/.node-version +1 -0
  203. package/templates/advanced/README.md.ejs +76 -0
  204. package/templates/advanced/__only_if_hasHttp__/src/servers/remote.ts.ejs +36 -0
  205. package/templates/advanced/__only_if_hasStdio__/src/servers/local.ts +30 -0
  206. package/templates/advanced/__only_if_useAxiosClient__/src/api/axios-client.ts +74 -0
  207. package/templates/advanced/__only_if_useCustomApiClient__/src/api/custom-client.ts +48 -0
  208. package/templates/advanced/__only_if_useCustomConvention__/src/conventions/custom-convention.ts +64 -0
  209. package/templates/advanced/__only_if_useCustomSearch__/src/api-extensions/custom-search-adapter.ts +30 -0
  210. package/templates/advanced/__only_if_useFetchClient__/src/api/fetch-client.ts +111 -0
  211. package/templates/advanced/__only_if_useFlatRestConvention__/src/conventions/flat-rest-convention.ts +85 -0
  212. package/templates/advanced/__only_if_usePinoLogger__/src/observability/logger.ts +62 -0
  213. package/templates/advanced/__only_if_useRansackSearch__/src/api-extensions/ransack-search-adapter.ts +41 -0
  214. package/templates/advanced/__only_if_useSharedModelAttrs__/src/models/app-base-model.ts +22 -0
  215. package/templates/advanced/__only_if_useVectorStorage__/src/storage/vector-store.ts +21 -0
  216. package/templates/advanced/__only_if_withAnalysis__/docker-compose.yml +18 -0
  217. package/templates/advanced/__only_if_withDomain__/src/domain/registry.ts +25 -0
  218. package/templates/advanced/config/schema.ts.ejs +126 -0
  219. package/templates/advanced/package.json.ejs +50 -0
  220. package/templates/advanced/src/config.ts.ejs +207 -0
  221. package/templates/advanced/src/db.ts.ejs +35 -0
  222. package/templates/advanced/src/models/_model_.ts.ejs +25 -0
  223. package/templates/advanced/src/models/index.ts.ejs +13 -0
  224. package/templates/advanced/src/profiles.ts +44 -0
  225. package/templates/advanced/src/prompts/_model_-prompt.ts.ejs +27 -0
  226. package/templates/advanced/src/prompts/index.ts.ejs +18 -0
  227. package/templates/advanced/src/scripts/db-migrate.ts +90 -0
  228. package/templates/advanced/src/tools/index.ts.ejs +133 -0
  229. package/templates/advanced/test/smoke.test.ts +16 -0
  230. package/templates/advanced/tsconfig.json +14 -0
  231. package/templates/simple/.env.example +3 -0
  232. package/templates/simple/.node-version +1 -0
  233. package/templates/simple/README.md +40 -0
  234. package/templates/simple/package.json.ejs +27 -0
  235. package/templates/simple/src/config.ts.ejs +56 -0
  236. package/templates/simple/src/models/_model_.ts.ejs +25 -0
  237. package/templates/simple/src/models/index.ts.ejs +13 -0
  238. package/templates/simple/src/prompts/_model_-prompt.ts.ejs +27 -0
  239. package/templates/simple/src/prompts/index.ts.ejs +18 -0
  240. package/templates/simple/src/server.ts +12 -0
  241. package/templates/simple/test/smoke.test.ts +16 -0
  242. package/templates/simple/tsconfig.json +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 David Sáenz Tagarro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # @mcp-rune/create
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@mcp-rune/create.svg)](https://www.npmjs.com/package/@mcp-rune/create)
4
+ [![CI](https://github.com/mcp-rune/mcp-rune-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/mcp-rune/mcp-rune-cli/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![MCP SDK](https://img.shields.io/badge/MCP_SDK-1.x-blue)](https://github.com/modelcontextprotocol/typescript-sdk)
7
+
8
+ Scaffolder for [mcp-rune](https://github.com/mcp-rune/mcp-rune)-based MCP servers.
9
+
10
+ ## Production installation
11
+
12
+ Install the CLI globally and run it:
13
+
14
+ ```bash
15
+ npm install -g @mcp-rune/create
16
+
17
+ # Interactive
18
+ rune new my-server
19
+
20
+ # Or with flags (CI-friendly)
21
+ rune new my-server --preset simple --yes
22
+ ```
23
+
24
+ Prefer a one-shot install-free run:
25
+
26
+ ```bash
27
+ # Interactive
28
+ npm create @mcp-rune@latest my-server
29
+
30
+ # Or with flags (CI-friendly)
31
+ npx @mcp-rune/create new my-server --preset simple --yes
32
+ ```
33
+
34
+ ## Local development
35
+
36
+ Use this path when working from a checkout of this repo (e.g. while the package is unpublished, or when contributing changes).
37
+
38
+ ```bash
39
+ # 1. Clone and enter the repo
40
+ git clone https://github.com/mcp-rune/mcp-rune-cli.git
41
+ cd mcp-rune-cli
42
+
43
+ # 2. Install deps and build dist/
44
+ npm install
45
+ npm run build
46
+
47
+ # 3. Expose a global `rune` command pointing at this checkout
48
+ npm link
49
+
50
+ # Now you can run it like the production examples:
51
+ rune new my-server --preset simple --yes
52
+ ```
53
+
54
+ Prefer not to symlink globally? Two alternatives:
55
+
56
+ ```bash
57
+ # Direct invocation against the built bin
58
+ node bin/rune.js new my-server --preset simple --yes
59
+
60
+ # Run straight from TypeScript source (no build step, picks up edits)
61
+ npm run dev -- new my-server --preset simple --yes
62
+ ```
63
+
64
+ To remove the global link later: `npm unlink -g @mcp-rune/create`.
65
+
66
+ ### Pointing scaffolded projects at a local mcp-rune checkout
67
+
68
+ `@mcp-rune/mcp-rune` is now on public npm, so `npm install` inside a scaffolded project works out of the box. The `--mcp-rune-local` escape hatch is still useful when you want edits in a local `mcp-rune` checkout to flow into the scaffolded project without a republish:
69
+
70
+ ```bash
71
+ # Flag form (absolute, ~, or relative paths all work)
72
+ rune new my-server --preset simple --yes \
73
+ --mcp-rune-local ~/Code/mcp-rune
74
+
75
+ # Env-var form (handy if you always work against the same checkout)
76
+ export MCP_RUNE_LOCAL_PATH=~/Code/mcp-rune
77
+ rune new my-server --preset simple --yes
78
+ ```
79
+
80
+ The CLI rewrites the `@mcp-rune/mcp-rune` dependency in the generated `package.json` to `file:/absolute/path/to/mcp-rune`, which npm symlinks into `node_modules/` — so edits in `~/Code/mcp-rune` flow through without reinstall. Prefix the path with `link:` instead (e.g. `--mcp-rune-local link:~/Code/mcp-rune`) if you want to use npm's link protocol explicitly.
81
+
82
+ ## Status
83
+
84
+ Early WIP. The Simple preset is the first target; Advanced (HTTP + OAuth + analysis) follows.
85
+
86
+ ## Commands
87
+
88
+ ```
89
+ rune new <project-name> Scaffold a new server
90
+ rune add model <Name> Add a model to an existing project (planned)
91
+ rune doctor Validate local env (planned)
92
+ rune db up Start docker pgvector + run migrations (analysis preset)
93
+ rune inspect Open MCP Inspector against the current project
94
+ ```
95
+
96
+ ## Presets
97
+
98
+ - **simple** — stdio transport, no DB, CRUD on declared models. `npm install && npm run start:local`.
99
+ - **advanced** — HTTP + OAuth, optional analysis (Docker pgvector), domain workflows, MCP Apps, profiles.
100
+
101
+ ### Database setup during `rune new`
102
+
103
+ When you scaffold an advanced project with `--with-analysis` (or accept analysis in the wizard), `rune new` prompts how to configure the database before running migrations:
104
+
105
+ - **docker** — starts the bundled `docker-compose.yml` (pgvector/pgvector:pg16), waits for the container to be healthy, then runs `npm run db:migrate`.
106
+ - **existing** — prompts for a `DATABASE_URL`, writes it to `.env`, then runs `npm run db:migrate`.
107
+ - **skip** — leaves the database untouched; the project's `Next steps` panel points at `rune db up` and the [database-setup guide](https://github.com/mcp-rune/mcp-rune/blob/master/docs/guides/11-reference/database-setup.md).
108
+
109
+ Under `--yes`, the default is `docker`. Simple and advanced-without-analysis projects skip this step entirely.
110
+
111
+ ## Flags & prompts
112
+
113
+ `rune new` is a wizard with an equivalent CLI flag for every interactive prompt — so the same choices can be made non-interactively, in CI, or scripted. The wizard asks **one** question in the simple preset (the mode picker) and the full pipeline in the advanced preset; `--yes` accepts every default and skips the wizard entirely.
114
+
115
+ | Prompt | Preset | Values | Default | Flag |
116
+ |---|---|---|---|---|
117
+ | How would you like to start? | both | `quick`, `customize`, `template` | `quick` | `--preset` / `--template` |
118
+ | Which preset? | both | `simple`, `advanced` | `simple` | `--preset` |
119
+ | Models to scaffold | both | comma list, e.g. `Book,Author` | (empty) | `--models` |
120
+ | Prompt strategy *(per model)* | advanced | `default`, `custom` | `default` | (none) |
121
+ | Tool classes to enable | advanced | `strategy`, `data`, `analysis`, `operations`, `domain` | `strategy, data, operations` | `--with-analysis`, `--with-domain` |
122
+ | API convention? | advanced | `jsonapi`, `rest-flat`, `custom` | `jsonapi` | `--api-convention` |
123
+ | API client? | advanced | `none`, `fetch`, `axios`, `custom` | `none` | `--api-client` |
124
+ | Search adapter? | advanced | `none`, `ransack`, `custom` | `none` | `--search-adapter` |
125
+ | DataLayer · enable vector storage hook? | advanced | yes / no | no | `--vector-storage` |
126
+ | ModelLayer · scaffold a shared BaseModel subclass? | advanced | yes / no | no | `--shared-model-attrs` |
127
+ | AnalysisLayer · enable analysis module? | advanced | yes / no | no | `--with-analysis` |
128
+ | Transport? | advanced | `stdio`, `http`, `both` | `both` | `--transport` |
129
+ | HTTP server auth? | advanced + http | `oauth`, `static-token` | `oauth` | `--server-auth` |
130
+ | Logger? | advanced | `framework`, `pino` | `framework` | `--logger` |
131
+ | Error tracking? | advanced | `none`, `sentry` | `none` | `--error-tracking` |
132
+ | Tracing? | advanced | `none`, `langfuse` | `none` | `--tracing` |
133
+ | Database setup? | advanced + analysis | `docker`, `existing-url`, `skip` | `docker` | `--db-setup`, `--database-url` |
134
+
135
+ ### Flags with no prompt equivalent
136
+
137
+ These change the run itself — they don't answer a question, so they only appear as flags.
138
+
139
+ | Flag | Effect |
140
+ |---|---|
141
+ | `--yes` | Accept all defaults; skip every interactive prompt. |
142
+ | `--dry-run` | Print the task plan; write nothing to disk. |
143
+ | `--verbose` | Stream subprocess output (`npm install`, `git init`, etc.) instead of spinners. |
144
+ | `--no-install` | Skip `npm install` after scaffolding. |
145
+ | `--no-git` | Skip `git init` after scaffolding. |
146
+ | `--skip-mascot` / `--fancy` | Suppress / force the welcome banner (auto-suppressed in CI and non-TTY). |
147
+ | `--offline-template <path>` | Use a local template directory instead of fetching via `tiged`. |
148
+ | `--mcp-rune-local <path>` | Point the scaffolded project at a local `mcp-rune` checkout (also reads `MCP_RUNE_LOCAL_PATH`). |
149
+
150
+ ## Templates
151
+
152
+ As an alternative to presets, scaffold from a runnable example in the [`mcp-rune/examples`](https://github.com/mcp-rune/examples) repo:
153
+
154
+ ```bash
155
+ rune new my-app --template bookshelf
156
+ ```
157
+
158
+ The CLI fetches the template at scaffold time via [`tiged`](https://github.com/tiged/tiged) — the project lands as a verbatim copy of the source repo. Templates are full apps with their own README, dependencies, and run instructions; presets are configuration-driven starters.
159
+
160
+ Registered templates:
161
+
162
+ - **bookshelf** — full mcp-rune surface (models, tools, prompts, interactive apps, optional GraphRAG) backed by an in-memory adapter. Zero external setup.
163
+
164
+ You can also point `--template` at any GitHub repo using degit-style shorthand:
165
+
166
+ ```bash
167
+ rune new my-app --template owner/repo
168
+ rune new my-app --template owner/repo/subdir
169
+ rune new my-app --template owner/repo/subdir#branch
170
+ ```
171
+
172
+ `--template` is mutually exclusive with `--preset` and the advanced extension flags.
173
+
174
+ ### Offline / corp-proxy fallback
175
+
176
+ If `tiged` can't reach GitHub (corp proxy, GitHub outage, air-gapped env), point `--offline-template` at a local clone of the template directory:
177
+
178
+ ```bash
179
+ rune new my-app --offline-template ~/clones/examples/bookshelf
180
+ ```
181
+
182
+ The CLI copies that directory verbatim instead of fetching. The dep-override and post-scaffold steps still run.
183
+
184
+ See `/Users/dsaenz/.config/claude/plans/we-need-to-design-pure-nest.md` for the design.
package/bin/rune.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { run } from '../dist/index.js';
3
+
4
+ run(process.argv).catch((err) => {
5
+ console.error(err.stack ?? err.message ?? err);
6
+ process.exit(1);
7
+ });
@@ -0,0 +1,5 @@
1
+ export interface AddModelOptions {
2
+ attrs?: string;
3
+ }
4
+ export declare function addModelCommand(modelName: string, opts: AddModelOptions): Promise<void>;
5
+ //# sourceMappingURL=add-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-model.d.ts","sourceRoot":"","sources":["../../src/commands/add-model.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA4D7F"}
@@ -0,0 +1,131 @@
1
+ import { existsSync, readFileSync, readdirSync, writeFileSync, mkdirSync } from 'node:fs';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import ejs from 'ejs';
5
+ import { error, hint, listAdd, listEdit, ok, space } from '../core/output.js';
6
+ import { pascal } from '../render/copy-tree.js';
7
+ const DEFAULT_ATTRIBUTES = [
8
+ { name: 'name', type: 'string', required: true, description: 'Name' },
9
+ { name: 'description', type: 'text', description: 'Description' },
10
+ ];
11
+ export async function addModelCommand(modelName, opts) {
12
+ const cwd = process.cwd();
13
+ const preset = detectPreset(cwd);
14
+ if (!preset) {
15
+ error('Not in a rune-scaffolded project.');
16
+ hint(' No src/server.ts or src/servers/local.ts found.');
17
+ process.exitCode = 1;
18
+ return;
19
+ }
20
+ const fileName = modelName.toLowerCase();
21
+ const namePascal = pascal(modelName);
22
+ const newModelPath = resolve(cwd, `src/models/${fileName}.ts`);
23
+ if (existsSync(newModelPath)) {
24
+ error(`Already exists: src/models/${fileName}.ts`);
25
+ process.exitCode = 1;
26
+ return;
27
+ }
28
+ const newPromptPath = resolve(cwd, `src/prompts/${fileName}-prompt.ts`);
29
+ if (existsSync(newPromptPath)) {
30
+ error(`Already exists: src/prompts/${fileName}-prompt.ts`);
31
+ process.exitCode = 1;
32
+ return;
33
+ }
34
+ const newModel = makeModel(modelName, parseAttrs(opts.attrs));
35
+ const existing = collectExistingModels(cwd);
36
+ const allModels = [...existing, newModel];
37
+ const vars = makeVars(cwd, preset, allModels);
38
+ const templateRoot = fileURLToPath(new URL(`../../templates/${preset}/`, import.meta.url));
39
+ await renderEjs(resolve(templateRoot, 'src/models/_model_.ts.ejs'), newModelPath, {
40
+ ...vars,
41
+ model: newModel,
42
+ });
43
+ await renderEjs(resolve(templateRoot, 'src/prompts/_model_-prompt.ts.ejs'), newPromptPath, {
44
+ ...vars,
45
+ model: newModel,
46
+ });
47
+ await renderEjs(resolve(templateRoot, 'src/models/index.ts.ejs'), resolve(cwd, 'src/models/index.ts'), vars);
48
+ await renderEjs(resolve(templateRoot, 'src/prompts/index.ts.ejs'), resolve(cwd, 'src/prompts/index.ts'), vars);
49
+ ok(`added model ${namePascal}`);
50
+ listAdd(`src/models/${fileName}.ts`);
51
+ listAdd(`src/prompts/${fileName}-prompt.ts`);
52
+ listEdit('src/models/index.ts');
53
+ listEdit('src/prompts/index.ts');
54
+ space();
55
+ hint(`Edit src/models/${fileName}.ts to declare attributes.`);
56
+ }
57
+ function detectPreset(cwd) {
58
+ if (existsSync(resolve(cwd, 'src/servers/local.ts')))
59
+ return 'advanced';
60
+ if (existsSync(resolve(cwd, 'src/server.ts')))
61
+ return 'simple';
62
+ return null;
63
+ }
64
+ function collectExistingModels(cwd) {
65
+ const modelsDir = resolve(cwd, 'src/models');
66
+ if (!existsSync(modelsDir))
67
+ return [];
68
+ return readdirSync(modelsDir)
69
+ .filter((f) => f.endsWith('.ts') && f !== 'index.ts')
70
+ .map((f) => f.replace(/\.ts$/, ''))
71
+ .map((fileName) => makeModel(fileName));
72
+ }
73
+ function makeModel(input, attributes = DEFAULT_ATTRIBUTES) {
74
+ const fileName = input.toLowerCase();
75
+ const namePascal = pascal(input);
76
+ return { name: namePascal, fileName, namePascal, attributes };
77
+ }
78
+ function parseAttrs(spec) {
79
+ if (!spec)
80
+ return DEFAULT_ATTRIBUTES;
81
+ return spec
82
+ .split(',')
83
+ .map((s) => s.trim())
84
+ .filter(Boolean)
85
+ .map((pair) => {
86
+ const [name = '', type = 'string'] = pair.split(':').map((x) => x.trim());
87
+ return {
88
+ name,
89
+ type: type,
90
+ description: name.replace(/_/g, ' '),
91
+ };
92
+ });
93
+ }
94
+ function makeVars(cwd, preset, models) {
95
+ const pkg = JSON.parse(readFileSync(resolve(cwd, 'package.json'), 'utf8'));
96
+ return {
97
+ projectName: pkg.name,
98
+ projectNamePascal: pascal(pkg.name),
99
+ preset,
100
+ models,
101
+ transport: 'stdio',
102
+ withAnalysis: false,
103
+ withDomain: false,
104
+ hasHttp: false,
105
+ hasStdio: true,
106
+ useFlatRestConvention: false,
107
+ useCustomConvention: false,
108
+ useFetchClient: false,
109
+ useAxiosClient: false,
110
+ useCustomApiClient: false,
111
+ useStaticTokenAuth: false,
112
+ useRansackSearch: false,
113
+ useCustomSearch: false,
114
+ useVectorStorage: false,
115
+ useSharedModelAttrs: false,
116
+ usePinoLogger: false,
117
+ useSentry: false,
118
+ useLangfuse: false,
119
+ toolClasses: [],
120
+ promptStrategies: {},
121
+ mcpRuneVersion: pkg.dependencies?.['@mcp-rune/mcp-rune'] ?? '^0.102.0',
122
+ nodeEngine: '>=24.0.0',
123
+ };
124
+ }
125
+ async function renderEjs(templatePath, outPath, vars) {
126
+ const content = readFileSync(templatePath, 'utf8');
127
+ const out = await ejs.render(content, vars, { async: true, escape: (s) => String(s) });
128
+ mkdirSync(dirname(outPath), { recursive: true });
129
+ writeFileSync(outPath, out);
130
+ }
131
+ //# sourceMappingURL=add-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-model.js","sourceRoot":"","sources":["../../src/commands/add-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function dbUpCommand(): Promise<void>;
2
+ //# sourceMappingURL=db-up.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-up.d.ts","sourceRoot":"","sources":["../../src/commands/db-up.ts"],"names":[],"mappings":"AAUA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BjD"}
@@ -0,0 +1,29 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { accent, fail, success } from '../core/color.js';
4
+ import { runMigrations, startDockerDb, waitForDbHealthy, } from '../core/db-setup.js';
5
+ import { error, ok, space, step } from '../core/output.js';
6
+ export async function dbUpCommand() {
7
+ const cwd = process.cwd();
8
+ if (!existsSync(resolve(cwd, 'docker-compose.yml'))) {
9
+ error('No docker-compose.yml in this directory.');
10
+ console.error(` Scaffold one with: ${accent('rune new <name> --preset advanced --with-analysis')}`);
11
+ process.exitCode = 1;
12
+ return;
13
+ }
14
+ step('docker compose up -d db');
15
+ await startDockerDb(cwd, { stdio: 'inherit' });
16
+ step('waiting for db to be healthy…');
17
+ const okHealthy = await waitForDbHealthy(cwd, 60_000);
18
+ if (!okHealthy) {
19
+ console.error(fail(' timed out — check `docker compose logs db`'));
20
+ process.exitCode = 1;
21
+ return;
22
+ }
23
+ console.log(success(' healthy'));
24
+ step('npm run db:migrate');
25
+ await runMigrations(cwd, { stdio: 'inherit' });
26
+ space();
27
+ ok('db is up; migrations applied');
28
+ }
29
+ //# sourceMappingURL=db-up.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-up.js","sourceRoot":"","sources":["../../src/commands/db-up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC;QACpD,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CACX,wBAAwB,MAAM,CAAC,mDAAmD,CAAC,EAAE,CACtF,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAChC,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE/C,IAAI,CAAC,+BAA+B,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAElC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAC3B,MAAM,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE/C,KAAK,EAAE,CAAC;IACR,EAAE,CAAC,8BAA8B,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CheckResult } from './index.js';
2
+ export type Check = () => Promise<CheckResult>;
3
+ export declare const CHECKS: Check[];
4
+ //# sourceMappingURL=env-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-checks.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/env-checks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;AAE/C,eAAO,MAAM,MAAM,EAAE,KAAK,EAiFzB,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { execa } from 'execa';
4
+ export const CHECKS = [
5
+ async () => {
6
+ const major = Number.parseInt(process.versions.node.split('.')[0], 10);
7
+ if (major >= 24)
8
+ return { status: 'ok', label: `Node.js ${process.versions.node}` };
9
+ if (major >= 22) {
10
+ return {
11
+ status: 'warn',
12
+ label: `Node.js ${process.versions.node}`,
13
+ hint: 'scaffolded projects require >= 24',
14
+ };
15
+ }
16
+ return {
17
+ status: 'fail',
18
+ label: `Node.js ${process.versions.node}`,
19
+ hint: 'CLI requires >= 22; scaffolded projects require >= 24',
20
+ };
21
+ },
22
+ async () => {
23
+ try {
24
+ const { stdout } = await execa('npm', ['--version']);
25
+ return { status: 'ok', label: `npm ${stdout.trim()}` };
26
+ }
27
+ catch {
28
+ return { status: 'fail', label: 'npm', hint: 'not found in PATH' };
29
+ }
30
+ },
31
+ async () => {
32
+ try {
33
+ await execa('docker', ['info'], { timeout: 3000 });
34
+ return { status: 'ok', label: 'Docker daemon reachable' };
35
+ }
36
+ catch {
37
+ return {
38
+ status: 'warn',
39
+ label: 'Docker not reachable',
40
+ hint: 'needed for the analysis module (skip if unused)',
41
+ };
42
+ }
43
+ },
44
+ async () => {
45
+ const pkgPath = resolve(process.cwd(), 'package.json');
46
+ if (!existsSync(pkgPath))
47
+ return { skip: true };
48
+ let pkg;
49
+ try {
50
+ pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
51
+ }
52
+ catch {
53
+ return { skip: true };
54
+ }
55
+ if (!pkg.dependencies?.['@mcp-rune/mcp-rune'])
56
+ return { skip: true };
57
+ const installed = existsSync(resolve(process.cwd(), 'node_modules/@mcp-rune/mcp-rune'));
58
+ return installed
59
+ ? { status: 'ok', label: '@mcp-rune/mcp-rune installed in this project' }
60
+ : {
61
+ status: 'warn',
62
+ label: '@mcp-rune/mcp-rune not installed in this project',
63
+ hint: 'run `npm install`',
64
+ };
65
+ },
66
+ async () => {
67
+ if (!existsSync(resolve(process.cwd(), 'docker-compose.yml')))
68
+ return { skip: true };
69
+ try {
70
+ const { stdout } = await execa('docker', ['compose', 'ps', '--format', 'json'], {
71
+ cwd: process.cwd(),
72
+ timeout: 3000,
73
+ });
74
+ const running = stdout.trim().length > 0;
75
+ return running
76
+ ? { status: 'ok', label: 'docker-compose services running' }
77
+ : {
78
+ status: 'warn',
79
+ label: 'docker-compose.yml present but no services running',
80
+ hint: 'run `rune db up`',
81
+ };
82
+ }
83
+ catch {
84
+ return { status: 'warn', label: 'docker-compose.yml present but compose not reachable' };
85
+ }
86
+ },
87
+ ];
88
+ //# sourceMappingURL=env-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-checks.js","sourceRoot":"","sources":["../../../src/commands/doctor/env-checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export type CheckResult = {
2
+ status: 'ok';
3
+ label: string;
4
+ hint?: string;
5
+ } | {
6
+ status: 'warn';
7
+ label: string;
8
+ hint?: string;
9
+ } | {
10
+ status: 'fail';
11
+ label: string;
12
+ hint?: string;
13
+ } | {
14
+ skip: true;
15
+ };
16
+ export interface DoctorOptions {
17
+ /** Path to a scaffolded project to additionally lint with validateRegistries. */
18
+ project?: string | true;
19
+ }
20
+ export declare function doctorCommand(opts?: DoctorOptions): Promise<void>;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAEnB,MAAM,WAAW,aAAa;IAC5B,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC3E"}
@@ -0,0 +1,44 @@
1
+ import { resolve } from 'node:path';
2
+ import { fail, muted, success, warn } from '../../core/color.js';
3
+ import { heading, space } from '../../core/output.js';
4
+ import { CHECKS } from './env-checks.js';
5
+ import { runProjectChecks } from './project-validation.js';
6
+ export async function doctorCommand(opts = {}) {
7
+ const results = [];
8
+ for (const check of CHECKS) {
9
+ const r = await check();
10
+ if ('skip' in r)
11
+ continue;
12
+ results.push(r);
13
+ print(r);
14
+ }
15
+ if (opts.project) {
16
+ const projectDir = opts.project === true ? process.cwd() : resolve(opts.project);
17
+ space();
18
+ heading(`Project schema check (${projectDir})`);
19
+ const projectResults = await runProjectChecks(projectDir);
20
+ for (const r of projectResults) {
21
+ results.push(r);
22
+ print(r);
23
+ }
24
+ }
25
+ const failed = results.filter((r) => r.status === 'fail').length;
26
+ const warned = results.filter((r) => r.status === 'warn').length;
27
+ space();
28
+ if (failed > 0) {
29
+ console.log(fail(`${failed} check(s) failed${warned ? `, ${warned} warning(s)` : ''}.`));
30
+ process.exitCode = 1;
31
+ }
32
+ else if (warned > 0) {
33
+ console.log(warn(`${warned} warning(s).`));
34
+ }
35
+ else {
36
+ console.log(success('All checks passed.'));
37
+ }
38
+ }
39
+ function print(r) {
40
+ const icon = r.status === 'ok' ? success('✓') : r.status === 'warn' ? warn('!') : fail('✗');
41
+ const suffix = r.hint ? muted(` — ${r.hint}`) : '';
42
+ console.log(`${icon} ${r.label}${suffix}`);
43
+ }
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAa3D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB,EAAE;IAC1D,MAAM,OAAO,GAA2C,EAAE,CAAC;IAE3D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,MAAM,KAAK,EAAE,CAAC;QACxB,IAAI,MAAM,IAAI,CAAC;YAAE,SAAS;QAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,KAAK,CAAC,CAAC,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjF,KAAK,EAAE,CAAC;QACR,OAAO,CAAC,yBAAyB,UAAU,GAAG,CAAC,CAAC;QAChD,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC1D,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,KAAK,CAAC,CAAC,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACjE,KAAK,EAAE,CAAC;IACR,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,mBAAmB,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACzF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;SAAM,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,cAAc,CAAC,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,CAAuC;IACpD,MAAM,IAAI,GACR,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { CheckResult } from './index.js';
2
+ export declare function runProjectChecks(projectDir: string): Promise<Exclude<CheckResult, {
3
+ skip: true;
4
+ }>[]>;
5
+ //# sourceMappingURL=project-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-validation.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/project-validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA6B9C,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,EAAE,CAAC,CAoFjD"}