@illumiarq/lumis 1.2.10 → 1.3.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 (296) hide show
  1. package/dist/bridges/project-bridge.d.ts +2 -0
  2. package/dist/bridges/project-bridge.d.ts.map +1 -0
  3. package/dist/bridges/project-bridge.js +174 -0
  4. package/dist/bridges/project-bridge.js.map +1 -0
  5. package/dist/cli.d.ts +1 -16
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +546 -170
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/app/cache-workflows.d.ts +7 -0
  10. package/dist/commands/app/cache-workflows.d.ts.map +1 -0
  11. package/dist/commands/app/cache-workflows.js +139 -0
  12. package/dist/commands/app/cache-workflows.js.map +1 -0
  13. package/dist/commands/app/command-runtime.d.ts +11 -0
  14. package/dist/commands/app/command-runtime.d.ts.map +1 -0
  15. package/dist/commands/app/command-runtime.js +41 -0
  16. package/dist/commands/app/command-runtime.js.map +1 -0
  17. package/dist/commands/app/config-cache.d.ts +3 -0
  18. package/dist/commands/app/config-cache.d.ts.map +1 -0
  19. package/dist/commands/app/config-cache.js +75 -0
  20. package/dist/commands/app/config-cache.js.map +1 -0
  21. package/dist/commands/app/config-publish.d.ts +2 -0
  22. package/dist/commands/app/config-publish.d.ts.map +1 -0
  23. package/dist/commands/app/config-publish.js +68 -0
  24. package/dist/commands/app/config-publish.js.map +1 -0
  25. package/dist/commands/app/config-stubs.d.ts +3 -0
  26. package/dist/commands/app/config-stubs.d.ts.map +1 -0
  27. package/dist/commands/app/config-stubs.js +154 -0
  28. package/dist/commands/app/config-stubs.js.map +1 -0
  29. package/dist/commands/app/database.d.ts +3 -0
  30. package/dist/commands/app/database.d.ts.map +1 -0
  31. package/dist/commands/app/database.js +221 -0
  32. package/dist/commands/app/database.js.map +1 -0
  33. package/dist/commands/app/docs.d.ts +7 -0
  34. package/dist/commands/app/docs.d.ts.map +1 -0
  35. package/dist/commands/app/docs.js +61 -0
  36. package/dist/commands/app/docs.js.map +1 -0
  37. package/dist/commands/app/routes.d.ts +7 -0
  38. package/dist/commands/app/routes.d.ts.map +1 -0
  39. package/dist/commands/app/routes.js +282 -0
  40. package/dist/commands/app/routes.js.map +1 -0
  41. package/dist/commands/app/security.d.ts +3 -0
  42. package/dist/commands/app/security.d.ts.map +1 -0
  43. package/dist/commands/app/security.js +15 -0
  44. package/dist/commands/app/security.js.map +1 -0
  45. package/dist/commands/app/worker-schedule.d.ts +5 -0
  46. package/dist/commands/app/worker-schedule.d.ts.map +1 -0
  47. package/dist/commands/app/worker-schedule.js +94 -0
  48. package/dist/commands/app/worker-schedule.js.map +1 -0
  49. package/dist/commands/app-commands.d.ts +19 -0
  50. package/dist/commands/app-commands.d.ts.map +1 -0
  51. package/dist/commands/app-commands.js +77 -0
  52. package/dist/commands/app-commands.js.map +1 -0
  53. package/dist/commands/build-vercel-fn.d.ts +9 -0
  54. package/dist/commands/build-vercel-fn.d.ts.map +1 -0
  55. package/dist/commands/build-vercel-fn.js +32 -0
  56. package/dist/commands/build-vercel-fn.js.map +1 -0
  57. package/dist/commands/build.d.ts +14 -0
  58. package/dist/commands/build.d.ts.map +1 -0
  59. package/dist/commands/build.js +24 -0
  60. package/dist/commands/build.js.map +1 -0
  61. package/dist/commands/info.d.ts +9 -0
  62. package/dist/commands/info.d.ts.map +1 -0
  63. package/dist/commands/info.js +41 -0
  64. package/dist/commands/info.js.map +1 -0
  65. package/dist/commands/keys.d.ts +3 -0
  66. package/dist/commands/keys.d.ts.map +1 -0
  67. package/dist/commands/keys.js +60 -0
  68. package/dist/commands/keys.js.map +1 -0
  69. package/dist/commands/maintenance.d.ts +9 -0
  70. package/dist/commands/maintenance.d.ts.map +1 -0
  71. package/dist/commands/maintenance.js +38 -0
  72. package/dist/commands/maintenance.js.map +1 -0
  73. package/dist/commands/module-list.d.ts +2 -0
  74. package/dist/commands/module-list.d.ts.map +1 -0
  75. package/dist/commands/module-list.js +27 -0
  76. package/dist/commands/module-list.js.map +1 -0
  77. package/dist/commands/preview.d.ts +14 -0
  78. package/dist/commands/preview.d.ts.map +1 -0
  79. package/dist/commands/preview.js +49 -0
  80. package/dist/commands/preview.js.map +1 -0
  81. package/dist/commands/serve.d.ts +16 -0
  82. package/dist/commands/serve.d.ts.map +1 -0
  83. package/dist/commands/serve.js +61 -0
  84. package/dist/commands/serve.js.map +1 -0
  85. package/dist/{output/ansi.d.ts → console.d.ts} +8 -4
  86. package/dist/console.d.ts.map +1 -0
  87. package/dist/{output/ansi.js → console.js} +12 -4
  88. package/dist/console.js.map +1 -0
  89. package/dist/index.d.ts +15 -19
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +12 -12
  92. package/dist/index.js.map +1 -1
  93. package/dist/paths.d.ts +26 -0
  94. package/dist/paths.d.ts.map +1 -0
  95. package/dist/paths.js +83 -0
  96. package/dist/paths.js.map +1 -0
  97. package/dist/server-wrapper.d.ts +12 -0
  98. package/dist/server-wrapper.d.ts.map +1 -0
  99. package/dist/server-wrapper.js +63 -0
  100. package/dist/server-wrapper.js.map +1 -0
  101. package/dist/vercel-wrapper.d.ts +6 -0
  102. package/dist/vercel-wrapper.d.ts.map +1 -0
  103. package/dist/vercel-wrapper.js +50 -0
  104. package/dist/vercel-wrapper.js.map +1 -0
  105. package/package.json +19 -37
  106. package/README.md +0 -38
  107. package/dist/adapter-loader.d.ts +0 -67
  108. package/dist/adapter-loader.d.ts.map +0 -1
  109. package/dist/adapter-loader.js +0 -273
  110. package/dist/adapter-loader.js.map +0 -1
  111. package/dist/commands/commands.command.d.ts +0 -38
  112. package/dist/commands/commands.command.d.ts.map +0 -1
  113. package/dist/commands/commands.command.js +0 -176
  114. package/dist/commands/commands.command.js.map +0 -1
  115. package/dist/commands/doctor.command.d.ts +0 -9
  116. package/dist/commands/doctor.command.d.ts.map +0 -1
  117. package/dist/commands/doctor.command.js +0 -922
  118. package/dist/commands/doctor.command.js.map +0 -1
  119. package/dist/commands/init.command.d.ts +0 -9
  120. package/dist/commands/init.command.d.ts.map +0 -1
  121. package/dist/commands/init.command.js +0 -135
  122. package/dist/commands/init.command.js.map +0 -1
  123. package/dist/commands/intent.command.d.ts +0 -26
  124. package/dist/commands/intent.command.d.ts.map +0 -1
  125. package/dist/commands/intent.command.js +0 -211
  126. package/dist/commands/intent.command.js.map +0 -1
  127. package/dist/commands/ir-rebuild.command.d.ts +0 -9
  128. package/dist/commands/ir-rebuild.command.d.ts.map +0 -1
  129. package/dist/commands/ir-rebuild.command.js +0 -36
  130. package/dist/commands/ir-rebuild.command.js.map +0 -1
  131. package/dist/commands/ir-show.command.d.ts +0 -9
  132. package/dist/commands/ir-show.command.d.ts.map +0 -1
  133. package/dist/commands/ir-show.command.js +0 -32
  134. package/dist/commands/ir-show.command.js.map +0 -1
  135. package/dist/commands/make.command.d.ts +0 -9
  136. package/dist/commands/make.command.d.ts.map +0 -1
  137. package/dist/commands/make.command.js +0 -93
  138. package/dist/commands/make.command.js.map +0 -1
  139. package/dist/commands/pack.command.d.ts +0 -16
  140. package/dist/commands/pack.command.d.ts.map +0 -1
  141. package/dist/commands/pack.command.js +0 -44
  142. package/dist/commands/pack.command.js.map +0 -1
  143. package/dist/commands/runtime.command.d.ts +0 -6
  144. package/dist/commands/runtime.command.d.ts.map +0 -1
  145. package/dist/commands/runtime.command.js +0 -379
  146. package/dist/commands/runtime.command.js.map +0 -1
  147. package/dist/commands/runtime.d.ts +0 -45
  148. package/dist/commands/runtime.d.ts.map +0 -1
  149. package/dist/commands/runtime.js +0 -66
  150. package/dist/commands/runtime.js.map +0 -1
  151. package/dist/commands/tinker-agent-plan.d.ts +0 -26
  152. package/dist/commands/tinker-agent-plan.d.ts.map +0 -1
  153. package/dist/commands/tinker-agent-plan.js +0 -115
  154. package/dist/commands/tinker-agent-plan.js.map +0 -1
  155. package/dist/commands/tinker-chat-commands.d.ts +0 -19
  156. package/dist/commands/tinker-chat-commands.d.ts.map +0 -1
  157. package/dist/commands/tinker-chat-commands.js +0 -263
  158. package/dist/commands/tinker-chat-commands.js.map +0 -1
  159. package/dist/commands/tinker-chat-runtime.d.ts +0 -30
  160. package/dist/commands/tinker-chat-runtime.d.ts.map +0 -1
  161. package/dist/commands/tinker-chat-runtime.js +0 -227
  162. package/dist/commands/tinker-chat-runtime.js.map +0 -1
  163. package/dist/commands/tinker-classic-mode.d.ts +0 -15
  164. package/dist/commands/tinker-classic-mode.d.ts.map +0 -1
  165. package/dist/commands/tinker-classic-mode.js +0 -160
  166. package/dist/commands/tinker-classic-mode.js.map +0 -1
  167. package/dist/commands/tinker-eval.command.d.ts +0 -3
  168. package/dist/commands/tinker-eval.command.d.ts.map +0 -1
  169. package/dist/commands/tinker-eval.command.js +0 -151
  170. package/dist/commands/tinker-eval.command.js.map +0 -1
  171. package/dist/commands/tinker-repl-display.d.ts +0 -15
  172. package/dist/commands/tinker-repl-display.d.ts.map +0 -1
  173. package/dist/commands/tinker-repl-display.js +0 -147
  174. package/dist/commands/tinker-repl-display.js.map +0 -1
  175. package/dist/commands/tinker-session-runtime.d.ts +0 -27
  176. package/dist/commands/tinker-session-runtime.d.ts.map +0 -1
  177. package/dist/commands/tinker-session-runtime.js +0 -196
  178. package/dist/commands/tinker-session-runtime.js.map +0 -1
  179. package/dist/commands/tinker.command.d.ts +0 -9
  180. package/dist/commands/tinker.command.d.ts.map +0 -1
  181. package/dist/commands/tinker.command.js +0 -142
  182. package/dist/commands/tinker.command.js.map +0 -1
  183. package/dist/commands/use.command.d.ts +0 -10
  184. package/dist/commands/use.command.d.ts.map +0 -1
  185. package/dist/commands/use.command.js +0 -69
  186. package/dist/commands/use.command.js.map +0 -1
  187. package/dist/config-loader.d.ts +0 -110
  188. package/dist/config-loader.d.ts.map +0 -1
  189. package/dist/config-loader.js +0 -119
  190. package/dist/config-loader.js.map +0 -1
  191. package/dist/launcher.d.ts +0 -16
  192. package/dist/launcher.d.ts.map +0 -1
  193. package/dist/launcher.js +0 -301
  194. package/dist/launcher.js.map +0 -1
  195. package/dist/lib/file-scanner.d.ts +0 -8
  196. package/dist/lib/file-scanner.d.ts.map +0 -1
  197. package/dist/lib/file-scanner.js +0 -70
  198. package/dist/lib/file-scanner.js.map +0 -1
  199. package/dist/lib/tinker-memory.d.ts +0 -19
  200. package/dist/lib/tinker-memory.d.ts.map +0 -1
  201. package/dist/lib/tinker-memory.js +0 -107
  202. package/dist/lib/tinker-memory.js.map +0 -1
  203. package/dist/lib/tinker-observer.d.ts +0 -47
  204. package/dist/lib/tinker-observer.d.ts.map +0 -1
  205. package/dist/lib/tinker-observer.js +0 -77
  206. package/dist/lib/tinker-observer.js.map +0 -1
  207. package/dist/lib/tinker-policy.d.ts +0 -21
  208. package/dist/lib/tinker-policy.d.ts.map +0 -1
  209. package/dist/lib/tinker-policy.js +0 -102
  210. package/dist/lib/tinker-policy.js.map +0 -1
  211. package/dist/lib/tinker-replay.d.ts +0 -51
  212. package/dist/lib/tinker-replay.d.ts.map +0 -1
  213. package/dist/lib/tinker-replay.js +0 -123
  214. package/dist/lib/tinker-replay.js.map +0 -1
  215. package/dist/output/ansi.d.ts.map +0 -1
  216. package/dist/output/ansi.js.map +0 -1
  217. package/dist/output/plan-display.d.ts +0 -4
  218. package/dist/output/plan-display.d.ts.map +0 -1
  219. package/dist/output/plan-display.js +0 -49
  220. package/dist/output/plan-display.js.map +0 -1
  221. package/dist/output/result-display.d.ts +0 -5
  222. package/dist/output/result-display.d.ts.map +0 -1
  223. package/dist/output/result-display.js +0 -17
  224. package/dist/output/result-display.js.map +0 -1
  225. package/dist/plugins/tinker-plugin.d.ts +0 -86
  226. package/dist/plugins/tinker-plugin.d.ts.map +0 -1
  227. package/dist/plugins/tinker-plugin.js +0 -42
  228. package/dist/plugins/tinker-plugin.js.map +0 -1
  229. package/dist/router-preferences.d.ts +0 -5
  230. package/dist/router-preferences.d.ts.map +0 -1
  231. package/dist/router-preferences.js +0 -22
  232. package/dist/router-preferences.js.map +0 -1
  233. package/dist/runtime/executor.d.ts +0 -33
  234. package/dist/runtime/executor.d.ts.map +0 -1
  235. package/dist/runtime/executor.js +0 -180
  236. package/dist/runtime/executor.js.map +0 -1
  237. package/dist/runtime/orchestration.d.ts +0 -43
  238. package/dist/runtime/orchestration.d.ts.map +0 -1
  239. package/dist/runtime/orchestration.js +0 -209
  240. package/dist/runtime/orchestration.js.map +0 -1
  241. package/dist/runtime/policy.d.ts +0 -49
  242. package/dist/runtime/policy.d.ts.map +0 -1
  243. package/dist/runtime/policy.js +0 -78
  244. package/dist/runtime/policy.js.map +0 -1
  245. package/dist/runtime/profiles.d.ts +0 -15
  246. package/dist/runtime/profiles.d.ts.map +0 -1
  247. package/dist/runtime/profiles.js +0 -131
  248. package/dist/runtime/profiles.js.map +0 -1
  249. package/dist/runtime/transcripts.d.ts +0 -59
  250. package/dist/runtime/transcripts.d.ts.map +0 -1
  251. package/dist/runtime/transcripts.js +0 -172
  252. package/dist/runtime/transcripts.js.map +0 -1
  253. package/dist/tools/git-diff.d.ts +0 -3
  254. package/dist/tools/git-diff.d.ts.map +0 -1
  255. package/dist/tools/git-diff.js +0 -16
  256. package/dist/tools/git-diff.js.map +0 -1
  257. package/dist/tools/index.d.ts +0 -24
  258. package/dist/tools/index.d.ts.map +0 -1
  259. package/dist/tools/index.js +0 -88
  260. package/dist/tools/index.js.map +0 -1
  261. package/dist/tools/lint.d.ts +0 -3
  262. package/dist/tools/lint.d.ts.map +0 -1
  263. package/dist/tools/lint.js +0 -35
  264. package/dist/tools/lint.js.map +0 -1
  265. package/dist/tools/read-file.d.ts +0 -3
  266. package/dist/tools/read-file.d.ts.map +0 -1
  267. package/dist/tools/read-file.js +0 -47
  268. package/dist/tools/read-file.js.map +0 -1
  269. package/dist/tools/run-command.d.ts +0 -3
  270. package/dist/tools/run-command.d.ts.map +0 -1
  271. package/dist/tools/run-command.js +0 -71
  272. package/dist/tools/run-command.js.map +0 -1
  273. package/dist/tools/run-tests.d.ts +0 -3
  274. package/dist/tools/run-tests.d.ts.map +0 -1
  275. package/dist/tools/run-tests.js +0 -49
  276. package/dist/tools/run-tests.js.map +0 -1
  277. package/dist/tools/tool-dispatch.d.ts +0 -32
  278. package/dist/tools/tool-dispatch.d.ts.map +0 -1
  279. package/dist/tools/tool-dispatch.js +0 -120
  280. package/dist/tools/tool-dispatch.js.map +0 -1
  281. package/dist/tools/typecheck.d.ts +0 -3
  282. package/dist/tools/typecheck.d.ts.map +0 -1
  283. package/dist/tools/typecheck.js +0 -48
  284. package/dist/tools/typecheck.js.map +0 -1
  285. package/dist/tools/types.d.ts +0 -62
  286. package/dist/tools/types.d.ts.map +0 -1
  287. package/dist/tools/types.js +0 -7
  288. package/dist/tools/types.js.map +0 -1
  289. package/dist/tools/write-file.d.ts +0 -15
  290. package/dist/tools/write-file.d.ts.map +0 -1
  291. package/dist/tools/write-file.js +0 -52
  292. package/dist/tools/write-file.js.map +0 -1
  293. package/dist/tracing/types.d.ts +0 -10
  294. package/dist/tracing/types.d.ts.map +0 -1
  295. package/dist/tracing/types.js +0 -2
  296. package/dist/tracing/types.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1,192 +1,568 @@
1
+ #!/usr/bin/env node
1
2
  /**
2
- * Host CLI entrypoint and command dispatcher.
3
+ * @illumiarq/lumis extended CLI entry point.
3
4
  *
4
- * Commands are declared in a registry and resolved by longest prefix match,
5
- * enabling subcommands with free-form trailing arguments (e.g. `intent <text>`).
5
+ * Intercepts LumiARQ-specific commands (serve / build / preview) and
6
+ * delegates everything else to the base @lumiarq/lumis runCli().
6
7
  */
7
- import { executeIntentCommand } from './commands/intent.command.js';
8
- import { executeIrRebuildCommand } from './commands/ir-rebuild.command.js';
9
- import { executeIrShowCommand } from './commands/ir-show.command.js';
10
- import { executeMakeCommand } from './commands/make.command.js';
11
- import { executeCommandsListCommand, executeCommandsRunCommand } from './commands/commands.command.js';
12
- import { executeDoctorCommand } from './commands/doctor.command.js';
13
- import { executeInitCommand } from './commands/init.command.js';
14
- import { executeUseCommand } from './commands/use.command.js';
15
- import { ansi } from './output/ansi.js';
16
- import { executePackDetectCommand, executePackListCommand } from './commands/pack.command.js';
17
- import { executeRuntimeRunCommand, executeRuntimeTranscriptsListCommand, executeRuntimeTranscriptsPruneCommand, executeRuntimeTranscriptsShowCommand, } from './commands/runtime.command.js';
18
- import { createCommandContext } from './commands/runtime.js';
19
- import { executeTinkerCommand } from './commands/tinker.command.js';
20
- import { executeTinkerEvalCommand } from './commands/tinker-eval.command.js';
21
- import { runInteractiveLauncher } from './launcher.js';
22
- import { pathToFileURL } from 'node:url';
23
- const COMMANDS = [
24
- { path: ['use'], description: 'Set preferred AI runtime', handler: executeUseCommand },
25
- { path: ['pack', 'list'], description: 'List built-in packs', handler: executePackListCommand },
26
- { path: ['pack', 'detect'], description: 'Detect best pack for project', handler: executePackDetectCommand },
27
- { path: ['commands', 'list'], description: 'List pack and project commands', handler: executeCommandsListCommand },
28
- { path: ['commands', 'run'], description: 'Run a pack or project command', handler: executeCommandsRunCommand },
29
- { path: ['doctor'], description: 'Run Lumis diagnostics for this project', handler: executeDoctorCommand },
30
- { path: ['init'], description: 'Initialize Lumis in this project', handler: executeInitCommand },
31
- { path: ['make'], description: 'Create artifacts from intent', handler: executeMakeCommand },
32
- { path: ['intent'], description: 'Parse and inspect intent', handler: executeIntentCommand },
33
- { path: ['ir', 'show'], description: 'Show current IR', handler: executeIrShowCommand },
34
- { path: ['ir', 'rebuild'], description: 'Rebuild project IR', handler: executeIrRebuildCommand },
35
- { path: ['runtime', 'run'], description: 'Run runtime profile tasks', handler: executeRuntimeRunCommand },
36
- { path: ['runtime', 'transcripts', 'list'], description: 'List runtime transcripts', handler: executeRuntimeTranscriptsListCommand },
37
- { path: ['runtime', 'transcripts', 'show'], description: 'Show runtime transcript details', handler: executeRuntimeTranscriptsShowCommand },
38
- { path: ['runtime', 'transcripts', 'prune'], description: 'Prune runtime transcripts', handler: executeRuntimeTranscriptsPruneCommand },
39
- { path: ['tinker', 'eval'], description: 'Run Tinker evaluation harness', handler: executeTinkerEvalCommand },
40
- { path: ['tinker'], description: 'Run interactive tinker mode', handler: executeTinkerCommand },
41
- ];
42
- function createTraceListener() {
43
- if (process.env.LUMIS_TRACE !== '1') {
44
- return undefined;
8
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ import { ui, writeError, writeLine } from './console.js';
11
+ import { readStorageRoot } from './paths.js';
12
+ import { serveApp } from './commands/serve.js';
13
+ import { buildApp } from './commands/build.js';
14
+ import { buildVercelFunction } from './commands/build-vercel-fn.js';
15
+ import { previewApp } from './commands/preview.js';
16
+ import { showInfo } from './commands/info.js';
17
+ import { listModules } from './commands/module-list.js';
18
+ import { generateKeys, rotateKeys } from './commands/keys.js';
19
+ import { enableMaintenanceMode, disableMaintenanceMode } from './commands/maintenance.js';
20
+ import { cacheConfig, cacheRoutes, cacheSearchIndex, cacheViews, checkRoutes, clearConfigCache, clearOptimizationCaches, clearRouteCache, clearSearchIndex, clearViews, installAuth, listRoutes, makeLayout, makePage, optimizeForProduction, publishConfig, publishStubs, runDatabaseCommand, scheduleList, scheduleRun, showResolvedConfig, workerList, workerStart, } from './commands/app-commands.js';
21
+ const argv = process.argv.slice(2);
22
+ const cmd = argv[0];
23
+ async function main() {
24
+ if (argv.includes('--help') || cmd === 'help') {
25
+ return renderCombinedHelp();
26
+ }
27
+ // ── LumiARQ-specific commands ──────────────────────────────────────────────
28
+ if (cmd === 'serve') {
29
+ const port = parsePort(argv);
30
+ const host = parseHost(argv);
31
+ return serveApp({ ...(port !== undefined ? { port } : {}), ...(host ? { host } : {}) });
32
+ }
33
+ if (cmd === 'preview') {
34
+ const port = parsePort(argv);
35
+ const target = parsePreviewTarget(argv);
36
+ return previewApp({ ...(port !== undefined ? { port } : {}), ...(target ? { target } : {}) });
37
+ }
38
+ if (cmd === 'build') {
39
+ const target = parseTarget(argv);
40
+ return buildApp(target !== undefined ? { target } : {});
41
+ }
42
+ if (cmd === 'build:vercel') {
43
+ return buildApp({ target: 'vercel' });
44
+ }
45
+ if (cmd === 'build:vercel-fn') {
46
+ return buildVercelFunction();
47
+ }
48
+ if (cmd === 'info') {
49
+ return showInfo();
50
+ }
51
+ if (cmd === 'health') {
52
+ runHealthPreChecks();
53
+ const { runCli } = await import('@lumiarq/lumis');
54
+ return runCli(['doctor', ...argv.slice(1)]);
55
+ }
56
+ if (cmd === 'doctor') {
57
+ runHealthPreChecks();
58
+ const { runCli } = await import('@lumiarq/lumis');
59
+ return runCli(argv);
60
+ }
61
+ if (cmd === 'module:list') {
62
+ return listModules();
63
+ }
64
+ if (cmd === 'test') {
65
+ return runTest(argv.slice(1));
66
+ }
67
+ if (cmd === 'prettier:sync') {
68
+ return syncPrettierConfig();
69
+ }
70
+ if (cmd === 'key:generate') {
71
+ return generateKeys();
72
+ }
73
+ if (cmd === 'key:rotate') {
74
+ return rotateKeys();
75
+ }
76
+ if (cmd === 'config:show') {
77
+ const configName = argv[1];
78
+ if (!configName) {
79
+ writeError(ui.fail('Usage: lumis config:show <name> [--json]'));
80
+ return 1;
81
+ }
82
+ return showResolvedConfig(configName);
83
+ }
84
+ if (cmd === 'config:cache') {
85
+ return cacheConfig();
86
+ }
87
+ if (cmd === 'config:clear') {
88
+ return clearConfigCache();
89
+ }
90
+ if (cmd?.startsWith('db:')) {
91
+ return await runDatabaseCommand(cmd, argv.slice(1));
92
+ }
93
+ if (cmd === 'route:list') {
94
+ return listRoutes();
95
+ }
96
+ if (cmd === 'route:check') {
97
+ return checkRoutes();
98
+ }
99
+ if (cmd === 'route:cache') {
100
+ return cacheRoutes();
101
+ }
102
+ if (cmd === 'make:page') {
103
+ return makePage(argv[1] ?? '', process.cwd(), argv.includes('--force'));
104
+ }
105
+ if (cmd === 'make:layout') {
106
+ return makeLayout(argv[1] ?? '', process.cwd(), argv.includes('--force'));
107
+ }
108
+ if (cmd === 'route:clear') {
109
+ return clearRouteCache();
110
+ }
111
+ if (cmd === 'view:cache') {
112
+ return cacheViews();
113
+ }
114
+ if (cmd === 'view:clear') {
115
+ return clearViews();
116
+ }
117
+ if (cmd === 'search:index') {
118
+ return cacheSearchIndex();
119
+ }
120
+ if (cmd === 'search:clear') {
121
+ return clearSearchIndex();
45
122
  }
46
- return async (event) => {
47
- const payload = {
48
- type: event.type,
49
- name: event.name,
50
- status: event.status,
51
- ...(event.message ? { message: event.message } : {}),
52
- ...(event.context ? { context: event.context } : {}),
53
- };
54
- process.stderr.write(`[lumis-trace] ${JSON.stringify(payload)}\n`);
55
- };
123
+ if (cmd === 'optimize') {
124
+ return optimizeForProduction();
125
+ }
126
+ if (cmd === 'optimize:clear') {
127
+ return clearOptimizationCaches();
128
+ }
129
+ if (cmd === 'down') {
130
+ const message = parseStringFlag(argv, '--message');
131
+ const secret = parseStringFlag(argv, '--secret');
132
+ const allowedIps = parseRepeatedFlag(argv, '--allow');
133
+ return enableMaintenanceMode({
134
+ ...(message ? { message } : {}),
135
+ ...(secret ? { secret } : {}),
136
+ ...(allowedIps.length > 0 ? { allowedIps } : {}),
137
+ });
138
+ }
139
+ if (cmd === 'up') {
140
+ return disableMaintenanceMode();
141
+ }
142
+ if (cmd === 'stub:publish') {
143
+ return publishStubs({ all: argv.includes('--all'), iam: argv.includes('--iam') });
144
+ }
145
+ if (cmd === 'auth:install') {
146
+ const uiFramework = parseStringFlag(argv, '--ui');
147
+ return installAuth({
148
+ iam: argv.includes('--iam'),
149
+ ...(uiFramework ? { ui: uiFramework } : {}),
150
+ });
151
+ }
152
+ if (cmd === 'publish') {
153
+ const subCmd = argv[1];
154
+ if (subCmd === 'config') {
155
+ const configName = argv[2] ?? 'list';
156
+ return publishConfig(configName, argv.includes('--force'));
157
+ }
158
+ if (subCmd === 'stub' || subCmd === 'stubs') {
159
+ return publishStubs({ all: argv.includes('--all'), iam: argv.includes('--iam') });
160
+ }
161
+ writeError(ui.fail(`Unknown publish subcommand: "${subCmd}". Try: publish config <name>`));
162
+ return 1;
163
+ }
164
+ if (cmd === 'worker:start') {
165
+ return workerStart(argv.includes('--dev'));
166
+ }
167
+ if (cmd === 'worker:list') {
168
+ return workerList();
169
+ }
170
+ if (cmd === 'schedule:list') {
171
+ return scheduleList();
172
+ }
173
+ if (cmd === 'schedule:run') {
174
+ return scheduleRun(argv[1] ?? '');
175
+ }
176
+ const projectCommandExit = await runProjectCommandDirect(argv);
177
+ if (projectCommandExit !== null) {
178
+ return projectCommandExit;
179
+ }
180
+ // ── Delegate to base @lumiarq/lumis (lazy import avoids auto-run side effect)
181
+ const { runCli } = await import('@lumiarq/lumis');
182
+ return runCli(argv);
56
183
  }
57
- async function emitTrace(onTrace, event) {
58
- if (!onTrace)
59
- return;
60
- await onTrace(event);
184
+ async function renderCombinedHelp() {
185
+ renderWrapperHelp();
186
+ writeLine(ui.section('Base Lumis Commands'));
187
+ const { runCli } = await import('@lumiarq/lumis');
188
+ return runCli(['--help']);
61
189
  }
62
- function formatUsage() {
63
- const lines = [
64
- ansi.label('Core CLI'),
65
- ` ${ansi.dim('Prompt -> Plan -> Confirm -> Execute -> Verified Result')}`,
66
- '',
67
- `${ansi.bold('Usage')}:`,
68
- ` ${ansi.cyan('lumis --help')}`,
69
- ];
70
- for (const command of COMMANDS) {
71
- lines.push(` ${ansi.cyan(`lumis ${command.path.join(' ')}`)} ${ansi.dim(`# ${command.description}`)}`);
72
- }
73
- return `${lines.join('\n')}\n`;
190
+ function renderWrapperHelp() {
191
+ writeLine();
192
+ writeLine(ui.section('LumiARQ CLI'));
193
+ writeLine(` ${ui.dim('Wrapper commands are shown first; core Lumis commands remain available underneath.')}`);
194
+ writeLine();
195
+ writeLine(` ${ui.bold('Runtime')}`);
196
+ writeLine(' lumis serve [--port|-p <port>] [--host|-H <host>]');
197
+ writeLine(' lumis build [--target|--to|--t|-t <node|static|cloudflare|vercel>]');
198
+ writeLine(' lumis build:vercel');
199
+ writeLine(' lumis preview [--target|--to|--t|-t <node|static|cloudflare>]');
200
+ writeLine();
201
+ writeLine(` ${ui.bold('App')}`);
202
+ writeLine(' lumis info');
203
+ writeLine(' lumis health');
204
+ writeLine(' lumis module:list');
205
+ writeLine(' lumis config:show <name>');
206
+ writeLine(' lumis config:cache | config:clear');
207
+ writeLine(' lumis route:list | route:check | route:cache | route:clear');
208
+ writeLine(' lumis make:page <route> [--force]');
209
+ writeLine(' lumis make:layout <route> [--force]');
210
+ writeLine(' lumis view:cache | view:clear');
211
+ writeLine(' lumis search:index | search:clear');
212
+ writeLine(' lumis optimize | optimize:clear');
213
+ writeLine(' lumis key:generate | key:rotate');
214
+ writeLine(' lumis down [--message <text>] [--secret <token>] [--allow <ip>]');
215
+ writeLine(' lumis up');
216
+ writeLine(' lumis auth:install [--iam] [--ui react]');
217
+ writeLine(' lumis stub:publish [--all|--iam]');
218
+ writeLine();
219
+ writeLine(` ${ui.bold('Database')}`);
220
+ writeLine(' lumis db:generate | db:migrate');
221
+ writeLine(' lumis db:ping — verify DB connection and diagnose failures');
222
+ writeLine(' lumis db:seed');
223
+ writeLine(' lumis db:fresh — migrate + seed (destructive)');
224
+ writeLine(' lumis db:reset — drop all tables + migrate');
225
+ writeLine(' lumis db:studio — open drizzle-kit studio');
226
+ writeLine();
227
+ writeLine(` ${ui.bold('Config')}`);
228
+ writeLine(' lumis publish config <name> — mail | queue | cache | storage | session | security | logging | auth');
229
+ writeLine(' lumis publish config all — publish every config file');
230
+ writeLine(' lumis publish config list — show available configs');
231
+ writeLine();
232
+ writeLine(` ${ui.bold('Workers & Scheduling')}`);
233
+ writeLine(' lumis worker:start [--dev] — start background worker process');
234
+ writeLine(' lumis worker:list — list registered workers + scheduled jobs');
235
+ writeLine(' lumis schedule:list — list all cron jobs');
236
+ writeLine(' lumis schedule:run <name> — run a specific cron job immediately');
237
+ writeLine();
238
+ writeLine(` ${ui.bold('Core Lumis')}`);
239
+ writeLine(' lumis doctor | init | make | intent | ir:* | runtime:* | tinker');
240
+ writeLine();
241
+ writeLine(` ${ui.bold('Project Commands')}`);
242
+ writeLine(' lumis <your:command> — run projectCommands entries directly');
243
+ writeLine(' lumis commands run project <name>');
244
+ writeLine();
74
245
  }
75
- /**
76
- * Resolve command using longest prefix semantics.
77
- *
78
- * Example:
79
- * - argv: ['intent', 'create', 'record']
80
- * - match: ['intent'] with args ['create', 'record']
81
- *
82
- * @param argv - Raw command tokens after the executable name.
83
- * @returns Matched command and trailing arguments, or null when no command matches.
84
- */
85
- function matchCommand(argv) {
86
- const matches = COMMANDS.filter((command) => {
87
- if (command.path.length > argv.length) {
88
- return false;
89
- }
90
- return command.path.every((segment, index) => segment === argv[index]);
91
- }).sort((left, right) => right.path.length - left.path.length);
92
- const command = matches[0];
93
- if (!command) {
246
+ const BASE_COMMAND_ROOTS = new Set([
247
+ 'use',
248
+ 'pack',
249
+ 'commands',
250
+ 'doctor',
251
+ 'init',
252
+ 'make',
253
+ 'intent',
254
+ 'ir',
255
+ 'runtime',
256
+ 'tinker',
257
+ ]);
258
+ async function runProjectCommandDirect(args) {
259
+ const candidate = args[0];
260
+ if (!candidate) {
261
+ return null;
262
+ }
263
+ if (BASE_COMMAND_ROOTS.has(candidate)) {
264
+ return null;
265
+ }
266
+ const { runCli } = await import('@lumiarq/lumis');
267
+ let stdout = '';
268
+ let stderr = '';
269
+ const listExit = await runCli(['commands', 'list', '--json'], {
270
+ write: (chunk) => {
271
+ stdout += chunk;
272
+ },
273
+ writeError: (chunk) => {
274
+ stderr += chunk;
275
+ },
276
+ });
277
+ if (listExit !== 0 || stderr.trim().length > 0) {
278
+ return null;
279
+ }
280
+ let commands = [];
281
+ try {
282
+ commands = JSON.parse(stdout);
283
+ }
284
+ catch {
94
285
  return null;
95
286
  }
96
- return {
97
- command,
98
- args: argv.slice(command.path.length),
99
- };
287
+ const exists = commands.some((entry) => entry.source === 'project' && entry.name === candidate);
288
+ if (!exists) {
289
+ return null;
290
+ }
291
+ return runCli(['commands', 'run', 'project', candidate, ...args.slice(1)]);
100
292
  }
101
- /**
102
- * Execute the host CLI command flow.
103
- *
104
- * @param argv - CLI arguments excluding the node/script prefix.
105
- * @param options - Optional execution overrides for project root and output writers.
106
- * @returns Exit code (0 success, non-zero failure).
107
- */
108
- export async function runCli(argv, options = {}) {
109
- const write = options.write ?? ((message) => process.stdout.write(message));
110
- const writeError = options.writeError ?? ((message) => process.stderr.write(message));
111
- const onTrace = createTraceListener();
112
- const stdin = options.stdin ?? process.stdin;
113
- const stdout = options.stdout ?? process.stdout;
114
- const interactiveMode = options.interactiveMode ?? 'auto';
115
- const shouldRunInteractiveMenu = argv.length === 0 &&
116
- !argv.includes('--help') &&
117
- (interactiveMode === 'on' ||
118
- (interactiveMode === 'auto' && process.env.CI !== 'true' && process.env.LUMIS_NO_TUI !== '1' && stdin.isTTY && stdout.isTTY));
119
- if (shouldRunInteractiveMenu) {
120
- await emitTrace(onTrace, {
121
- type: 'command-dispatch',
122
- status: 'start',
123
- name: 'interactive-launcher',
124
- context: { mode: interactiveMode },
125
- });
126
- const launcherResult = await runInteractiveLauncher({
127
- projectRoot: options.projectRoot ?? process.cwd(),
128
- write,
129
- stdin,
130
- stdout,
131
- });
132
- if (launcherResult.kind === 'exit') {
133
- await emitTrace(onTrace, {
134
- type: 'command-dispatch',
135
- status: launcherResult.code === 0 ? 'success' : 'failure',
136
- name: 'interactive-launcher',
137
- context: { exitCode: launcherResult.code },
293
+ async function runTest(extraArgs) {
294
+ const cwd = process.cwd();
295
+ const { execSync } = await import('node:child_process');
296
+ // Prefer flat pkg/vitest.config.ts; fall back to legacy pkg/vitest/config.ts
297
+ const flatConfig = join(cwd, 'pkg', 'vitest.config.ts');
298
+ const subdirConfig = join(cwd, 'pkg', 'vitest', 'config.ts');
299
+ const configPath = existsSync(flatConfig)
300
+ ? flatConfig
301
+ : existsSync(subdirConfig)
302
+ ? subdirConfig
303
+ : null;
304
+ const configFlag = configPath ? ['--config', configPath] : [];
305
+ const vitestArgs = ['vitest', 'run', ...configFlag, ...extraArgs].join(' ');
306
+ try {
307
+ execSync(`pnpm exec ${vitestArgs}`, { stdio: 'inherit', cwd });
308
+ return 0;
309
+ }
310
+ catch {
311
+ return 1;
312
+ }
313
+ }
314
+ async function syncPrettierConfig() {
315
+ const cwd = process.cwd();
316
+ const { writeFileSync } = await import('node:fs');
317
+ const { pathToFileURL } = await import('node:url');
318
+ const srcPath = join(cwd, 'pkg', 'prettier.config.ts');
319
+ if (!existsSync(srcPath)) {
320
+ writeError(ui.fail('pkg/prettier.config.ts not found. Create it first.\n'));
321
+ return 1;
322
+ }
323
+ let config;
324
+ try {
325
+ const mod = await import(pathToFileURL(srcPath).href);
326
+ config = mod.default ?? mod;
327
+ }
328
+ catch (e) {
329
+ writeError(ui.fail(`Failed to load pkg/prettier.config.ts: ${String(e)}\n`));
330
+ return 1;
331
+ }
332
+ const out = [
333
+ '// Auto-generated by lumis prettier:sync — edit pkg/prettier.config.ts instead.',
334
+ '// Run `lumis prettier:sync` to regenerate after changing pkg/prettier.config.ts.',
335
+ "/** @type {import('prettier').Config} */",
336
+ `export default ${JSON.stringify(config, null, 2)};`,
337
+ '',
338
+ ].join('\n');
339
+ writeFileSync(join(cwd, 'prettier.config.mjs'), out, 'utf8');
340
+ writeLine(ui.ok('prettier.config.mjs generated from pkg/prettier.config.ts'));
341
+ return 0;
342
+ }
343
+ function runHealthPreChecks() {
344
+ const cwd = process.cwd();
345
+ const checks = [];
346
+ // Required bootstrap files
347
+ checks.push({
348
+ label: 'bootstrap/entry.ts present',
349
+ pass: existsSync(join(cwd, 'bootstrap', 'entry.ts')),
350
+ fix: 'bootstrap/entry.ts is missing — this is the HTTP server entrypoint.',
351
+ });
352
+ checks.push({
353
+ label: 'bootstrap/providers.ts present',
354
+ pass: existsSync(join(cwd, 'bootstrap', 'providers.ts')),
355
+ fix: "bootstrap/providers.ts is missing — service container won't boot.",
356
+ });
357
+ checks.push({
358
+ label: 'src/config/app.ts present',
359
+ pass: existsSync(join(cwd, 'src', 'config', 'app.ts')),
360
+ fix: 'src/config/app.ts is missing — run: lumis publish config app',
361
+ });
362
+ checks.push({
363
+ label: '@types/node installed',
364
+ pass: existsSync(join(cwd, 'node_modules', '@types', 'node')) ||
365
+ existsSync(join(cwd, '..', 'node_modules', '@types', 'node')),
366
+ fix: 'Install @types/node: pnpm add -D @types/node',
367
+ });
368
+ checks.push({
369
+ label: 'drizzle config uses canonical pkg path',
370
+ pass: !existsSync(join(cwd, 'drizzle.config.ts')) ||
371
+ existsSync(join(cwd, 'pkg', 'drizzle.config.ts')) ||
372
+ existsSync(join(cwd, 'pkg', 'drizzle', 'config.ts')), // legacy subdir — migrate to flat
373
+ fix: 'Move Drizzle config to pkg/drizzle.config.ts. No root shim needed — lumis db:* reads pkg/ directly.',
374
+ });
375
+ checks.push({
376
+ label: 'vitest config uses canonical pkg path',
377
+ pass: !existsSync(join(cwd, 'vitest.config.ts')) ||
378
+ existsSync(join(cwd, 'pkg', 'vitest.config.ts')) ||
379
+ existsSync(join(cwd, 'pkg', 'vitest', 'config.ts')), // legacy subdir — migrate to flat
380
+ fix: 'Move Vitest config to pkg/vitest.config.ts. No root shim needed — lumis test reads pkg/ directly.',
381
+ });
382
+ checks.push({
383
+ label: 'lumis config uses canonical pkg path',
384
+ pass: (!existsSync(join(cwd, 'lumis.config.ts')) && !existsSync(join(cwd, 'lumis.config.json'))) ||
385
+ existsSync(join(cwd, 'pkg', 'lumis.config.ts')) ||
386
+ existsSync(join(cwd, 'pkg', 'lumis', 'config.ts')), // legacy subdir — migrate to flat
387
+ fix: 'Move lumis config to pkg/lumis.config.ts and remove the root lumis.config.* file.',
388
+ });
389
+ checks.push({
390
+ label: 'prettier config uses canonical pkg path',
391
+ pass: !existsSync(join(cwd, '.prettierrc')) || existsSync(join(cwd, 'pkg', 'prettier.config.ts')),
392
+ fix: 'Create pkg/prettier.config.ts and run `lumis prettier:sync` to generate prettier.config.mjs. Then delete .prettierrc.',
393
+ });
394
+ // Warn if queue driver isn't stub but worker.ts is missing
395
+ const queueConfigPath = existsSync(join(cwd, 'src', 'config', 'queue.ts'))
396
+ ? join(cwd, 'src', 'config', 'queue.ts')
397
+ : join(cwd, 'config', 'queue.ts'); // legacy fallback
398
+ if (existsSync(queueConfigPath)) {
399
+ const queueSrc = readFileSync(queueConfigPath, 'utf8');
400
+ const usesBullmq = queueSrc.includes("'bullmq'") || queueSrc.includes('"bullmq"');
401
+ if (usesBullmq) {
402
+ checks.push({
403
+ label: 'bootstrap/worker.ts present (queue driver: bullmq)',
404
+ pass: existsSync(join(cwd, 'bootstrap', 'worker.ts')),
405
+ fix: "Queue driver is 'bullmq' but bootstrap/worker.ts is missing. Create it to process queued jobs.",
138
406
  });
139
- return launcherResult.code;
140
407
  }
141
- argv = launcherResult.argv;
142
- }
143
- if (argv.includes('--help') || argv.length === 0) {
144
- await emitTrace(onTrace, {
145
- type: 'command-dispatch',
146
- status: 'info',
147
- name: 'help',
148
- context: { argvLength: argv.length },
149
- });
150
- write(formatUsage());
151
- return 0;
152
408
  }
153
- const matched = matchCommand(argv);
154
- if (!matched) {
155
- await emitTrace(onTrace, {
156
- type: 'command-dispatch',
157
- status: 'failure',
158
- name: 'unknown-command',
159
- message: argv.join(' '),
409
+ // Vercel deployment hygiene (Phase 0)
410
+ const vercelJsonPath = join(cwd, 'vercel.json');
411
+ if (existsSync(vercelJsonPath)) {
412
+ let vercelRaw = '';
413
+ try {
414
+ vercelRaw = readFileSync(vercelJsonPath, 'utf8');
415
+ }
416
+ catch {
417
+ vercelRaw = '';
418
+ }
419
+ const usesLegacyRoutes = vercelRaw.includes('"routes"') &&
420
+ vercelRaw.includes('"handle"') &&
421
+ vercelRaw.includes('filesystem');
422
+ checks.push({
423
+ label: 'vercel.json uses rewrites (not legacy routes + filesystem)',
424
+ pass: !usesLegacyRoutes && vercelRaw.includes('"rewrites"'),
425
+ fix: 'Replace deprecated routes/handle:filesystem with rewrites → /api/index. See lumiarq-vercel-deployment-fix skill.',
426
+ });
427
+ checks.push({
428
+ label: 'vercel.json installCommand pins pnpm',
429
+ pass: vercelRaw.includes('"installCommand"') && vercelRaw.includes('pnpm'),
430
+ fix: 'Add installCommand: "corepack enable && pnpm install --frozen-lockfile" to vercel.json.',
431
+ });
432
+ checks.push({
433
+ label: 'vercel.json bundles framework cache for serverless',
434
+ pass: vercelRaw.includes('"includeFiles"') && vercelRaw.includes('src/storage/framework/cache'),
435
+ fix: 'Add functions.api/index.js.includeFiles: "src/storage/framework/cache/**" so route/view caches ship with the function.',
160
436
  });
161
- writeError(`${ansi.fail(`Unknown command: ${argv.join(' ')}`)}\n`);
162
- write(formatUsage());
163
- return 1;
164
437
  }
165
- await emitTrace(onTrace, {
166
- type: 'command-dispatch',
167
- status: 'start',
168
- name: matched.command.path.join(' '),
169
- context: { args: matched.args },
438
+ checks.push({
439
+ label: 'api/index.js present (run pnpm run build:vercel first)',
440
+ pass: existsSync(join(cwd, 'api', 'index.js')),
441
+ fix: 'Run pnpm run build:vercel locally — Vercel requires api/index.js as the serverless entry.',
170
442
  });
171
- const context = await createCommandContext({
172
- argv,
173
- commandPath: matched.command.path,
174
- commandArgs: matched.args,
175
- projectRoot: options.projectRoot ?? process.cwd(),
176
- write,
177
- writeError,
178
- ...(onTrace ? { onTrace } : {}),
443
+ // Route loader cache path checks (Wave 2 canonical layout)
444
+ const storageRoot = readStorageRoot(cwd);
445
+ const routesLoader = join(cwd, storageRoot, 'framework', 'cache', 'routes.loader.ts');
446
+ const staleRootStorageLoader = join(cwd, 'storage', 'framework', 'cache', 'routes.loader.ts');
447
+ if (storageRoot !== 'storage' && existsSync(staleRootStorageLoader)) {
448
+ checks.push({
449
+ label: 'no stale root storage/ cache (use configured storage root)',
450
+ pass: false,
451
+ fix: `Remove storage/framework/cache — lumis should write to ${storageRoot}/framework/cache only.`,
452
+ });
453
+ }
454
+ const bootstrapRoutesLoader = join(cwd, 'bootstrap', 'cache', 'routes.loader.ts');
455
+ checks.push({
456
+ label: 'route loader cache path is canonical',
457
+ pass: !(existsSync(routesLoader) && existsSync(bootstrapRoutesLoader)),
458
+ fix: `Duplicate route cache detected. Keep only ${storageRoot}/framework/cache/routes.loader.ts and remove bootstrap/cache/routes.loader.ts`,
179
459
  });
180
- return matched.command.handler(context);
460
+ // Stale route loader warning
461
+ if (existsSync(routesLoader)) {
462
+ const loaderMtime = statSync(routesLoader).mtimeMs;
463
+ const routesRoot = join(cwd, 'src', 'modules');
464
+ let stale = false;
465
+ if (existsSync(routesRoot)) {
466
+ const stack = [routesRoot];
467
+ while (stack.length > 0) {
468
+ const dir = stack.pop();
469
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
470
+ if (entry.isDirectory()) {
471
+ stack.push(join(dir, entry.name));
472
+ continue;
473
+ }
474
+ if (/\/http\/routes\/.+\.(ts|js)$/.test(join(dir, entry.name))) {
475
+ if (statSync(join(dir, entry.name)).mtimeMs > loaderMtime) {
476
+ stale = true;
477
+ break;
478
+ }
479
+ }
480
+ }
481
+ if (stale)
482
+ break;
483
+ }
484
+ }
485
+ checks.push({
486
+ label: 'route cache is fresh',
487
+ pass: !stale,
488
+ fix: 'Route files have changed since last cache. Run: lumis route:cache',
489
+ });
490
+ }
491
+ const warnings = checks.filter((c) => !c.pass);
492
+ if (warnings.length > 0) {
493
+ writeLine();
494
+ writeLine(ui.section('Health Pre-checks'));
495
+ for (const w of warnings) {
496
+ writeLine(` ${ui.warn(w.label)}`);
497
+ if (w.fix)
498
+ writeLine(` ${ui.dim(w.fix)}`);
499
+ }
500
+ writeLine();
501
+ }
502
+ }
503
+ function parsePort(args) {
504
+ const idx = args.findIndex((a) => a === '--port' || a === '-p');
505
+ const inline = args.find((a) => a.startsWith('--port='));
506
+ const raw = inline ? inline.split('=')[1] : idx !== -1 ? args[idx + 1] : undefined;
507
+ if (raw)
508
+ return parseInt(raw, 10);
509
+ return undefined;
510
+ }
511
+ function parseHost(args) {
512
+ const idx = args.findIndex((a) => a === '--host' || a === '-H');
513
+ const inline = args.find((a) => a.startsWith('--host='));
514
+ if (inline)
515
+ return inline.split('=')[1];
516
+ if (idx !== -1)
517
+ return args[idx + 1];
518
+ return undefined;
519
+ }
520
+ function parseTarget(args) {
521
+ const idx = args.findIndex((a) => a === '--target' || a === '--to' || a === '--t' || a === '-t');
522
+ const inline = args.find((a) => a.startsWith('--target=') || a.startsWith('--to=') || a.startsWith('--t='));
523
+ if (inline) {
524
+ const val = inline.slice(inline.indexOf('=') + 1);
525
+ if (val === 'node' || val === 'static' || val === 'cloudflare' || val === 'vercel')
526
+ return val;
527
+ }
528
+ if (idx !== -1) {
529
+ const val = args[idx + 1];
530
+ if (val === 'node' || val === 'static' || val === 'cloudflare' || val === 'vercel')
531
+ return val;
532
+ }
533
+ return undefined;
181
534
  }
182
- function isMainModule() {
183
- const argv1 = process.argv[1];
184
- if (!argv1) {
185
- return false;
535
+ function parsePreviewTarget(args) {
536
+ const target = parseTarget(args);
537
+ if (target === 'vercel') {
538
+ writeError(ui.fail('`preview` does not support target "vercel". Use: lumis build --target vercel'));
539
+ return undefined;
540
+ }
541
+ return target;
542
+ }
543
+ function parseStringFlag(args, flag) {
544
+ const index = args.findIndex((value) => value === flag);
545
+ const inline = args.find((value) => value.startsWith(`${flag}=`));
546
+ if (inline) {
547
+ return inline.slice(flag.length + 1);
548
+ }
549
+ if (index !== -1) {
550
+ return args[index + 1];
186
551
  }
187
- return import.meta.url === pathToFileURL(argv1).href;
552
+ return undefined;
188
553
  }
189
- if (isMainModule()) {
190
- void runCli(process.argv.slice(2));
554
+ function parseRepeatedFlag(args, flag) {
555
+ const values = [];
556
+ for (let index = 0; index < args.length; index += 1) {
557
+ const token = args[index];
558
+ if (token === flag && args[index + 1]) {
559
+ values.push(args[index + 1]);
560
+ }
561
+ if (token?.startsWith(`${flag}=`)) {
562
+ values.push(token.slice(flag.length + 1));
563
+ }
564
+ }
565
+ return values;
191
566
  }
567
+ main().then((code) => process.exit(code));
192
568
  //# sourceMappingURL=cli.js.map