@fluojs/cli 1.1.0 → 3.0.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 (137) hide show
  1. package/README.ko.md +183 -22
  2. package/README.md +186 -22
  3. package/dist/cli.d.ts +5 -4
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +128 -35
  6. package/dist/commands/diagnostics.d.ts +35 -0
  7. package/dist/commands/diagnostics.d.ts.map +1 -1
  8. package/dist/commands/diagnostics.js +60 -0
  9. package/dist/commands/generate.d.ts +1 -49
  10. package/dist/commands/generate.d.ts.map +1 -1
  11. package/dist/commands/generate.js +1 -214
  12. package/dist/commands/inspect.d.ts +5 -7
  13. package/dist/commands/inspect.d.ts.map +1 -1
  14. package/dist/commands/inspect.js +85 -65
  15. package/dist/commands/migrate.d.ts.map +1 -1
  16. package/dist/commands/migrate.js +27 -15
  17. package/dist/commands/migration-transform-tokens.d.ts +15 -0
  18. package/dist/commands/migration-transform-tokens.d.ts.map +1 -0
  19. package/dist/commands/migration-transform-tokens.js +41 -0
  20. package/dist/commands/new.d.ts +0 -6
  21. package/dist/commands/new.d.ts.map +1 -1
  22. package/dist/commands/new.js +42 -96
  23. package/dist/commands/output-path-safety.d.ts +14 -0
  24. package/dist/commands/output-path-safety.d.ts.map +1 -0
  25. package/dist/commands/output-path-safety.js +34 -0
  26. package/dist/commands/scripts.d.ts +1 -1
  27. package/dist/commands/scripts.d.ts.map +1 -1
  28. package/dist/commands/scripts.js +13 -7
  29. package/dist/commands/typegen-artifact.d.ts +54 -0
  30. package/dist/commands/typegen-artifact.d.ts.map +1 -0
  31. package/dist/commands/typegen-artifact.js +117 -0
  32. package/dist/commands/typegen-generation-child.d.ts +2 -0
  33. package/dist/commands/typegen-generation-child.d.ts.map +1 -0
  34. package/dist/commands/typegen-generation-child.js +59 -0
  35. package/dist/commands/typegen-generation-process.d.ts +46 -0
  36. package/dist/commands/typegen-generation-process.d.ts.map +1 -0
  37. package/dist/commands/typegen-generation-process.js +131 -0
  38. package/dist/commands/typegen-generation-protocol.d.ts +16 -0
  39. package/dist/commands/typegen-generation-protocol.d.ts.map +1 -0
  40. package/dist/commands/typegen-generation-protocol.js +35 -0
  41. package/dist/commands/typegen-isolated-source.d.ts +10 -0
  42. package/dist/commands/typegen-isolated-source.d.ts.map +1 -0
  43. package/dist/commands/typegen-isolated-source.js +75 -0
  44. package/dist/commands/typegen-options.d.ts +20 -0
  45. package/dist/commands/typegen-options.d.ts.map +1 -0
  46. package/dist/commands/typegen-options.js +71 -0
  47. package/dist/commands/typegen-source.d.ts +59 -0
  48. package/dist/commands/typegen-source.d.ts.map +1 -0
  49. package/dist/commands/typegen-source.js +183 -0
  50. package/dist/commands/typegen-watch.d.ts +46 -0
  51. package/dist/commands/typegen-watch.d.ts.map +1 -0
  52. package/dist/commands/typegen-watch.js +212 -0
  53. package/dist/commands/typegen.d.ts +29 -0
  54. package/dist/commands/typegen.d.ts.map +1 -0
  55. package/dist/commands/typegen.js +119 -0
  56. package/dist/dev-runner/node-restart-runner.d.ts +6 -0
  57. package/dist/dev-runner/node-restart-runner.d.ts.map +1 -1
  58. package/dist/dev-runner/node-restart-runner.js +64 -13
  59. package/dist/fixtures/inspect-react-app.module.d.ts +4 -0
  60. package/dist/fixtures/inspect-react-app.module.d.ts.map +1 -0
  61. package/dist/fixtures/inspect-react-app.module.js +32 -0
  62. package/dist/fixtures/typegen-react-app.module.d.ts +4 -0
  63. package/dist/fixtures/typegen-react-app.module.d.ts.map +1 -0
  64. package/dist/fixtures/typegen-react-app.module.js +33 -0
  65. package/dist/generate-command.d.ts +50 -0
  66. package/dist/generate-command.d.ts.map +1 -0
  67. package/dist/generate-command.js +214 -0
  68. package/dist/index.d.ts +6 -5
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +6 -5
  71. package/dist/new/install.js +1 -1
  72. package/dist/new/package-spec-resolver.d.ts.map +1 -1
  73. package/dist/new/package-spec-resolver.js +50 -59
  74. package/dist/new/prompt.d.ts +1 -0
  75. package/dist/new/prompt.d.ts.map +1 -1
  76. package/dist/new/prompt.js +40 -12
  77. package/dist/new/published-internal-dependencies.d.ts +20 -0
  78. package/dist/new/published-internal-dependencies.d.ts.map +1 -0
  79. package/dist/new/published-internal-dependencies.js +20 -0
  80. package/dist/new/react-vite-ssr-scaffold.d.ts +19 -0
  81. package/dist/new/react-vite-ssr-scaffold.d.ts.map +1 -0
  82. package/dist/new/react-vite-ssr-scaffold.js +108 -0
  83. package/dist/new/resolver.d.ts +2 -2
  84. package/dist/new/resolver.d.ts.map +1 -1
  85. package/dist/new/resolver.js +5 -1
  86. package/dist/new/scaffold.d.ts.map +1 -1
  87. package/dist/new/scaffold.js +177 -54
  88. package/dist/new/starter-profiles.d.ts +8 -4
  89. package/dist/new/starter-profiles.d.ts.map +1 -1
  90. package/dist/new/starter-profiles.js +52 -18
  91. package/dist/new/templates/react-vite-ssr/README.md.ejs +74 -0
  92. package/dist/new/templates/react-vite-ssr/playwright.config.ts.ejs +26 -0
  93. package/dist/new/templates/react-vite-ssr/src/app.test.ts.ejs +82 -0
  94. package/dist/new/templates/react-vite-ssr/src/app.ts.ejs +91 -0
  95. package/dist/new/templates/react-vite-ssr/src/entry-client.tsx.ejs +29 -0
  96. package/dist/new/templates/react-vite-ssr/src/entry-server.tsx.ejs +52 -0
  97. package/dist/new/templates/react-vite-ssr/src/load-manifest.test.ts.ejs +55 -0
  98. package/dist/new/templates/react-vite-ssr/src/load-manifest.ts.ejs +53 -0
  99. package/dist/new/templates/react-vite-ssr/src/main.ts.ejs +18 -0
  100. package/dist/new/templates/react-vite-ssr/src/page.tsx.ejs +43 -0
  101. package/dist/new/templates/react-vite-ssr/src/react-app.test.tsx.ejs +67 -0
  102. package/dist/new/templates/react-vite-ssr/src/react-app.tsx.ejs +46 -0
  103. package/dist/new/templates/react-vite-ssr/src/styles.css.ejs +25 -0
  104. package/dist/new/templates/react-vite-ssr/src/styles.d.ts.ejs +1 -0
  105. package/dist/new/templates/react-vite-ssr/tests/production-hydration.spec.ts.ejs +54 -0
  106. package/dist/new/templates/react-vite-ssr/tsconfig.json.ejs +16 -0
  107. package/dist/new/templates/react-vite-ssr/vite.client.config.ts.ejs +24 -0
  108. package/dist/new/templates/react-vite-ssr/vite.server.config.ts.ejs +17 -0
  109. package/dist/new/templates/react-vite-ssr/vitest.config.ts.ejs +10 -0
  110. package/dist/new/types.d.ts +4 -2
  111. package/dist/new/types.d.ts.map +1 -1
  112. package/dist/public-generate.d.ts +2 -0
  113. package/dist/public-generate.d.ts.map +1 -0
  114. package/dist/public-generate.js +1 -0
  115. package/dist/public-inspect.d.ts +13 -0
  116. package/dist/public-inspect.d.ts.map +1 -0
  117. package/dist/public-inspect.js +16 -0
  118. package/dist/public-new.d.ts +13 -0
  119. package/dist/public-new.d.ts.map +1 -0
  120. package/dist/public-new.js +16 -0
  121. package/dist/public-typegen.d.ts +14 -0
  122. package/dist/public-typegen.d.ts.map +1 -0
  123. package/dist/public-typegen.js +17 -0
  124. package/dist/run-cli.d.ts +2 -1
  125. package/dist/run-cli.d.ts.map +1 -1
  126. package/dist/studio/sidecar.d.ts.map +1 -1
  127. package/dist/studio/sidecar.js +106 -14
  128. package/dist/transforms/nestjs-migrate.d.ts +4 -1
  129. package/dist/transforms/nestjs-migrate.d.ts.map +1 -1
  130. package/dist/transforms/nestjs-migrate.js +625 -65
  131. package/dist/typegen-contract.d.ts +10 -0
  132. package/dist/typegen-contract.d.ts.map +1 -0
  133. package/dist/typegen-contract.js +9 -0
  134. package/dist/usage.d.ts +19 -0
  135. package/dist/usage.d.ts.map +1 -0
  136. package/dist/usage.js +178 -0
  137. package/package.json +19 -10
package/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # @fluojs/cli
2
2
 
3
3
  <p><strong><kbd>English</kbd></strong> <a href="./README.ko.md"><kbd>한국어</kbd></a></p>
4
+ <!-- fluo-cli-bootstrap-automation-boundary: explicit-platform-express, numeric-literal-single-argument-listen, manual-host-callback-string-env-multiple-listen -->
4
5
 
5
- The canonical CLI for fluo — bootstrap new applications, generate components, export runtime inspection data, and run code transforms.
6
+ The canonical CLI for fluo — bootstrap new applications, generate components and React page types, export runtime inspection data, and run code transforms.
7
+
8
+ Preparing for the coordinated Node 24 release? Follow the [consumer migration guide](../../docs/getting-started/migrate-node24.md) before upgrading packages.
6
9
 
7
10
  ## Table of Contents
8
11
 
@@ -30,7 +33,11 @@ pnpm dlx @fluojs/cli new my-app
30
33
 
31
34
  ## Release Contract
32
35
 
33
- - `@fluojs/cli` is a public package in the intended publish surface.
36
+ - `@fluojs/cli` and every generated Node HTTP, mixed, microservice, and React SSR + Fastify project require Node.js `>=24.0.0 <27`. Node builds target `node24` and Node starters use `@types/node@^24.0.0`. Bun and Deno starters retain native engines; the Workers Node engine constrains only local CLI/Wrangler tooling. Apply the [Node.js migration](../../docs/reference/node-support.md) before upgrading.
37
+ - `@fluojs/cli` requires Node.js `>=24.0.0 <27`; generated Bun, Deno, and Cloudflare Workers starters may target non-Node runtimes, but the CLI process itself runs on Node.js. Generated Node HTTP and mixed projects declare Node.js `>=24.0.0 <27` so listener-level RFC `QUERY` reaches framework dispatch; Node versions below 24 and Node 27+ are excluded. Node microservice-only projects retain their independent `>=24.0.0 <27` floor.
38
+ - `inspect` resolves `@fluojs/runtime` only when inspection runs and only from the inspected project's dependency tree. Install a runtime version compatible with your active Node.js version before using `fluo inspect`; other CLI commands remain available across the CLI's full Node.js `>=24.0.0 <27` range.
39
+ - Interactive `new` flows and optional interactive `inspect --mermaid` guidance resolve `@clack/prompts` only when needed. Both interactive and non-interactive commands support the CLI Node.js `>=24.0.0 <27` range.
40
+ - The CLI and generated Node.js starter toolchain use `tsx@^4.23.1`; generated gRPC starters require `@grpc/grpc-js@^1.14.4`. Refresh existing project lockfiles when adopting these patched floors.
34
41
  - The supported install paths are the global package (`npm install -g @fluojs/cli`, `pnpm add -g @fluojs/cli`, `bun add -g @fluojs/cli`, or `yarn global add @fluojs/cli`) and the no-install runner (`pnpm dlx @fluojs/cli ...`).
35
42
  - The published `fluo` bin is the `./bin/fluo.mjs` wrapper declared in `package.json`; that wrapper loads the dist-built CLI entrypoint at `../dist/cli.js`.
36
43
 
@@ -65,22 +72,45 @@ The update check is skipped in CI, non-TTY output, npm-script contexts, rerun-af
65
72
  Scaffold a complete starter application in seconds.
66
73
 
67
74
  ```bash
68
- fluo new my-app
75
+ fluo new my-app --package-manager pnpm
69
76
  cd my-app
70
77
  pnpm dev
71
78
  ```
72
79
 
80
+ This example pins `pnpm`, so every successful scaffold ends with the same completion block:
81
+
82
+ ```text
83
+ Done.
84
+ Next steps:
85
+ cd ./my-app
86
+ pnpm dev # runs fluo dev
87
+ ```
88
+
89
+ In non-interactive output, an install prints `Installing dependencies with pnpm...` and the package-manager output before that block, while `--no-install` prints `Skipping dependency installation.`. In an interactive terminal, the wizard reports the same install state through its status UI (`Dependencies installed` or `Dependency installation skipped`) instead of those non-interactive stdout lines, then prints the common completion block. A completed pnpm install writes `pnpm-lock.yaml`; `--no-install` leaves it absent until you run `pnpm install` in the generated project. If you omit `--package-manager pnpm`, the CLI selects a manager from the current invocation or workspace signals and falls back to pnpm, so both the next-step command and the lockfile become manager-specific; other managers write their own lockfile instead of `pnpm-lock.yaml` when installation runs.
90
+
73
91
  `fluo create` is an alias for `fluo new`. Use `fluo version`, `fluo help <command>`, `fluo doctor`/`fluo info`/`fluo analyze`, `fluo add`, and `fluo upgrade` for version checks, command help, diagnostics, first-party package shortcuts, and upgrade guidance.
74
92
 
75
- Generated Node.js `dev`, `build`, and `start` package scripts delegate to `fluo dev`, `fluo build`, and `fluo start`. The CLI owns the Node-oriented lifecycle command, prepends the project-local `node_modules/.bin` when invoking local toolchain binaries, and defaults `NODE_ENV` to `development` for `dev` and `production` for `build`/`start` when the caller has not set it explicitly. Bun, Deno, and Workers generated `dev` scripts keep the same `fluo dev` abstraction but default to Bun, Deno, or Wrangler native watch loops to reduce Node-supervised dev processes; use `fluo dev --runner fluo` (or `FLUO_DEV_RUNNER=fluo`) when you need the fluo-owned restart boundary for its debounce/hash reporter contract. Their production/deployment scripts are runtime-native: Bun uses `bun build ./src/main.ts --outdir ./dist --target bun` and `bun dist/main.js`, Deno uses `deno compile --allow-env --allow-net --output dist/app src/main.ts` and `./dist/app`, and Workers exposes Wrangler `preview`/`deploy` scripts instead of `start`. By default, `fluo dev` and `fluo start` show app logs only (application stdout/stderr) so the lifecycle output shape is unified where the CLI owns the process boundary. Use `--reporter pretty` when you want concise fluo-branded lifecycle status and `app │`-prefixed application stdout/stderr, and use `--verbose` (or `FLUO_VERBOSE=1`) when you need raw runtime/tooling watcher output for debugging.
93
+ Generated Node.js `dev`, `build`, and `start` package scripts delegate to `fluo dev`, `fluo build`, and `fluo start`. The CLI owns the Node-oriented lifecycle command, prepends the project-local `node_modules/.bin` when invoking local toolchain binaries, and defaults `NODE_ENV` to `development` for `dev` and `production` for `build`/`start` when the caller has not set it explicitly. Bun, Deno, and Workers generated `dev` scripts keep the same `fluo dev` abstraction but default to Bun, Deno, or Wrangler native watch loops to reduce Node-supervised dev processes; use `fluo dev --runner fluo` (or `FLUO_DEV_RUNNER=fluo`) when you need the fluo-owned restart boundary for its debounce/hash reporter contract. Their production/deployment scripts are runtime-native: Bun uses `bun build ./src/main.ts --outdir ./dist --target bun` and `bun dist/main.js`, Deno uses `deno compile --allow-env --allow-net --output dist/app src/main.ts` and `./dist/app`, and Workers exposes Wrangler `preview`/`deploy` scripts instead of `start`. The generated Deno `AppModule` snapshots application-owned environment values with `Deno.env.toObject()`, so its dev and compiled commands retain broad `--allow-env`; signal listeners do not require a separate Deno permission. By default, `fluo dev` and `fluo start` show app logs only (application stdout/stderr) so the lifecycle output shape is unified where the CLI owns the process boundary. Use `--reporter pretty` when you want concise fluo-branded lifecycle status and `app │`-prefixed application stdout/stderr, and use `--verbose` (or `FLUO_VERBOSE=1`) when you need raw runtime/tooling watcher output for debugging.
76
94
 
77
95
  Generated starters set their `@fluojs/cli` `devDependency` from the generator CLI package version that created the project, so lifecycle scripts such as `pnpm dev`, `pnpm build`, and `pnpm start` keep using the same CLI behavior that scaffolded the starter instead of a stale hard-coded range.
78
96
 
79
- Generated non-Deno starter `vite.config.ts` files import `fluoDecoratorsPlugin()` from `@fluojs/vite`, so decorator transform updates ship through the maintained Vite package instead of being copied inline into every new project.
97
+ In published mode, every other internal `@fluojs/*` dependency and dev dependency uses
98
+ `^<package version>` from that package's release manifest. The CLI build generates
99
+ this metadata after Changesets versioning and ships it in `dist`, so an unpacked
100
+ CLI does not need the monorepo or a registry lookup to scaffold. Versions remain
101
+ independent, including React's `0.x` line; they are not all set to the CLI's major.
102
+ This applies to every HTTP, microservice, mixed, React, Bun, Deno, and Workers
103
+ starter. Internal local-sandbox tarball overrides still take precedence.
80
104
 
81
- Generated non-Deno HTTP starters use a TDD-first Vitest layout: fast greeting unit tests and `greeting.slice.test.ts` stay colocated under `src/greeting/`, app dispatch tests stay in `src/app.test.ts`, and the default e2e-style request-pipeline tests live in `test/app.e2e.test.ts` with `createTestApp({ rootModule })` plus `app.request(...).send()`. The generated `vitest.config.ts` includes both `src/**/*.test.ts` and `test/**/*.test.ts`, while generated package scripts expose `test`, `test:watch`, `test:cov`, and `test:e2e`; existing `src/app.e2e.test.ts` tests can move to `test/app.e2e.test.ts` without changing the request helper.
105
+ Generated non-Deno standard starter `vite.config.ts` files import `fluoDecoratorsPlugin()` from `@fluojs/vite`, while the React SSR + Vite starter applies the same plugin in `vite.server.config.ts`. The React starter keeps decorator-bearing declarations in `src/app.ts` and JSX rendering in `.tsx` modules, so the supported `.ts` transform boundary stays explicit. Decorator transform updates therefore ship through the maintained Vite package instead of being copied inline into every new project.
82
106
 
83
- For generated Node.js application projects, `fluo dev` runs through a fluo-owned restart boundary by default. The runner watches source and common config inputs, debounces atomic-save bursts, hashes file content before restarting, loads `.env` for each Node app child process it spawns, and ignores noisy output/cache paths such as `node_modules`, `dist`, `.git`, `.fluo`, coverage, cache folders, and editor swap files. Pressing Ctrl+S without changing file content should not restart the app. Planned restarts and terminal shutdown first send `SIGTERM` to the current app child, then force-kill it after a bounded grace period so a non-cooperative child cannot hang the restart supervisor indefinitely. On terminal app child exit or crash outside a planned restart, the runner closes watchers, clears the pending restart timer and paths, unregisters its `SIGINT`/`SIGTERM` handlers, and exits with the child terminal code. This is full-process restart-on-watch, not module-level HMR; config watch reloads are a separate in-process config concern, and future HMR work must document which modules can be safely hot-swapped. Use `fluo dev --raw-watch` or `FLUO_DEV_RAW_WATCH=1` when you need the runtime-native Node watcher for debugging. Generated Bun/Deno/Workers projects delegate watch/reload behavior to `bun --watch`, `deno run --watch`, or `wrangler dev` by default; use `fluo dev --runner fluo` or `FLUO_DEV_RUNNER=fluo` when those projects should return to the fluo-owned restart runner, and use `FLUO_DEV_WATCH_IGNORE=path,pattern` to add extra ignored paths for that runner.
107
+ New non-Deno projects declare Vite `^8.2.2`, Vitest `^4.1.11`, and `@vitest/coverage-v8` `^4.1.11`. Generated ESM Vite configs use `build.rolldownOptions`; Babel handles standard decorators through `fluoDecoratorsPlugin()` before Rolldown/Oxc processes application code, while `vitest.config.ts` retains `fluoBabelDecoratorsPlugin()` from `@fluojs/testing/vitest`. Direct Oxc/esbuild decorator processing is not supported. Node.js `>=24.0.0 <27` and runtime-native starter metadata are unchanged. Existing projects are not rewritten; adopt the [generated toolchain baseline](../../docs/reference/toolchain-contract-matrix.md) explicitly when upgrading.
108
+
109
+ When upgrading an existing starter, remove the `ignore: ['src/**/*.test.ts']` rule from `babel.config.cjs`. Generated Babel configs no longer exclude test files, so the testing plugin also transforms decorators declared inside tests before Vitest 4 executes them.
110
+
111
+ Generated standard non-Deno HTTP starters use a TDD-first Vitest layout: fast greeting unit tests and `greeting.slice.test.ts` stay colocated under `src/greeting/`, app dispatch tests stay in `src/app.test.ts`, and the default e2e-style request-pipeline tests live in `test/app.e2e.test.ts` with `createTestApp({ rootModule })` plus `app.request(...).send()`. The React starter instead includes focused streamed SSR, DOM hydration, and production Playwright hydration tests. Its `test:browser` script starts the built Fastify server and fails on missing assets, hydration warnings, or navigation that bypasses the server-owned route.
112
+
113
+ For generated Node.js application projects, `fluo dev` runs through a fluo-owned restart boundary by default. The runner watches source and common config inputs, debounces atomic-save bursts, hashes file content before restarting, loads `.env` for each Node app child process it spawns, and ignores noisy output/cache paths such as `node_modules`, `dist`, `.git`, `.fluo`, coverage, cache folders, and editor swap files. Pressing Ctrl+S without changing file content should not restart the app. Planned restarts and terminal shutdown first send `SIGTERM` to the current app child, then force-kill it after a bounded grace period so a non-cooperative child cannot hang the restart supervisor indefinitely. On terminal app child exit or crash outside a planned restart, the runner closes watchers, clears the pending restart timer and paths, unregisters its `SIGINT`/`SIGTERM` handlers, and exits with the child terminal code. A terminal error from either the primary recursive watcher or a fallback directory watcher, a required source target that is missing or inaccessible before watcher registration, or an unavailable required fallback source watcher after recursive watching is unavailable follows that same cleanup path. This covers total fallback acquisition failure, partial failure after sibling watchers are acquired, and failure for a directory discovered while the fallback watcher is running; the runner terminates the current app child within the existing bound and exits with code `1` instead of leaving the child or sibling watchers running. This is full-process restart-on-watch, not module-level HMR; config watch reloads are a separate in-process config concern, and future HMR work must document which modules can be safely hot-swapped. Use `fluo dev --raw-watch` or `FLUO_DEV_RAW_WATCH=1` when you need the runtime-native Node watcher for debugging. Generated Bun/Deno/Workers projects delegate watch/reload behavior to `bun --watch`, `deno run --watch --allow-env --allow-net src/main.ts`, or `wrangler dev` by default; the Deno command preserves access to every application-owned environment key consumed through `Deno.env.toObject()`. Use `fluo dev --runner fluo` or `FLUO_DEV_RUNNER=fluo` when those projects should return to the fluo-owned restart runner, and use `FLUO_DEV_WATCH_IGNORE=path,pattern` to add extra ignored paths for that runner.
84
114
 
85
115
  `fluo new` supports Node.js + Fastify, Express, and raw Node.js HTTP application starters on the same Node-oriented install/build flow:
86
116
 
@@ -98,6 +128,29 @@ fluo new my-deno-app --shape application --transport http --runtime deno --platf
98
128
  fluo new my-worker-app --shape application --transport http --runtime cloudflare-workers --platform cloudflare-workers
99
129
  ```
100
130
 
131
+ Select the official HTTP-first React SSR + Vite application with the named starter flag:
132
+
133
+ ```bash
134
+ fluo new my-react-app --starter react-vite-ssr
135
+ ```
136
+
137
+ This starter fixes the schema to Node.js + Fastify HTTP. Run `pnpm dev`, open
138
+ `/products/sku-42?preview=true`, and edit `src/page.tsx`; page UI no longer needs to carry Vite assets,
139
+ the document shell, or the server/client route snapshot wiring. The explicit `@Router(...)` /
140
+ `@Path(...)` handler in `src/app.ts` returns that page as one `ReactElement`, so the existing HTTP
141
+ dispatcher remains authoritative.
142
+
143
+ Generated application wiring stays visible instead of becoming a framework abstraction:
144
+ `src/entry-server.tsx` owns the replaceable `ReactPageRenderer` and `ReactServerEntry` creation,
145
+ `src/react-app.tsx` shares one document and `ReactClientRouterProvider` composition between server and
146
+ client, `src/entry-client.tsx` calls `hydrateRoot(...)`, and `src/main.ts` uses
147
+ `src/load-manifest.ts` to load the generated Vite manifest before `@fluojs/react/vite` parses it.
148
+ Missing build output, incompatible entry selectors, and hydration mismatches identify those exact
149
+ application files and the lifecycle command to rerun. Generated `Link` output remains a real anchor
150
+ and `router.push(...)` performs full-document navigation through the HTTP dispatcher. The starter
151
+ intentionally excludes RSC, Server Functions, file routing, a client route table, SPA document
152
+ swapping, prefetch, and a data cache.
153
+
101
154
  `fluo new` also exposes microservice starter paths. TCP is the default when you omit `--transport`, and the starter matrix includes runnable Redis Streams, NATS, Kafka, RabbitMQ, MQTT, and gRPC variants with transport-specific dependencies, env templates, and entrypoints:
102
155
 
103
156
  ```bash
@@ -112,7 +165,7 @@ fluo new my-grpc-service --shape microservice --transport grpc --runtime node --
112
165
 
113
166
  Supported `--shape microservice --transport` starter values are exactly `tcp`, `redis-streams`, `nats`, `kafka`, `rabbitmq`, `mqtt`, and `grpc`. Use `redis-streams` for the maintained Redis-backed starter, or add `@fluojs/redis` manually after scaffolding when you need broader Redis integration patterns.
114
167
 
115
- The NATS/Kafka/RabbitMQ starter contracts stay explicit about external brokers and caller-owned client libraries. Generated projects wire `nats` + `JSONCodec()`, `kafkajs` producer/consumer collaborators, and `amqplib` publisher/consumer collaborators directly in `src/app.ts` so the starter contract is runnable without pretending the base fluo packages hide those dependencies. Those broker clients are created lazily by the generated transport wrapper when the Fluo lifecycle starts listening, sends, or emits; importing `src/app.ts` for `fluo inspect`, tests, or static tooling does not connect to a broker or open external resources before the application lifecycle owns teardown.
168
+ The NATS/Kafka/RabbitMQ starter contracts stay explicit about external brokers and caller-owned client libraries. Generated projects wire `nats` + `JSONCodec()`, `kafkajs` producer/consumer collaborators, and `amqplib` publisher/consumer collaborators directly in `src/app.ts` so the starter contract is runnable without pretending the base fluo packages hide those dependencies. Those broker clients are created lazily by the generated transport wrapper when the Fluo lifecycle starts listening, sends, or emits; importing `src/app.ts` for `fluo inspect`, tests, or static tooling does not connect to a broker or open external resources before the application lifecycle owns teardown. During shutdown, each wrapper still attempts to close its owned clients when delegated transport shutdown fails. Kafka partial connection failures disconnect acquired clients, and RabbitMQ channel creation failures close the acquired connection before the startup error is rethrown.
116
169
 
117
170
  The starter matrix also includes a mixed single-package starter: one Fastify HTTP app with an attached TCP microservice in the same generated project.
118
171
 
@@ -120,19 +173,32 @@ The starter matrix also includes a mixed single-package starter: one Fastify HTT
120
173
  fluo new my-mixed-app --shape mixed --transport tcp --runtime node --platform fastify
121
174
  ```
122
175
 
123
- When `fluo new` runs in an interactive TTY, the wizard uses the same flags/config model. It asks for the project name, shape-first branch (`application` -> runtime + HTTP platform, `microservice` -> transport), the maintained tooling preset, package-manager choice, whether to install dependencies immediately, and whether to initialize a git repository. Non-interactive flags and programmatic `runNewCommand(...)` calls use the same resolved defaults.
176
+ When `fluo new` runs in an interactive TTY, the wizard uses the same flags/config model. It first offers the standard backend and React SSR + Vite named starters. The standard branch then asks for the shape-first path (`application` -> runtime + HTTP platform, `microservice` -> transport); the React branch uses its fixed Node.js + Fastify HTTP contract. Both continue with the maintained tooling preset, package-manager choice, dependency installation, and git initialization. Non-interactive flags and programmatic `runNewCommand(...)` calls use the same resolved defaults.
177
+
178
+ By default, `fluo new my-app` writes to `./my-app`. Use `--target-directory <path>` when the project name and destination path should differ, or when automation should write to an explicit directory:
179
+
180
+ ```bash
181
+ fluo new my-app --target-directory ./apps/api
182
+ ```
183
+
184
+ Scaffolding refuses to overwrite conflicting files in a non-empty target by default. Add `--force` only when you intentionally want generated files with different contents to be overwritten:
185
+
186
+ ```bash
187
+ fluo new my-app --target-directory ./apps/api --force
188
+ ```
124
189
 
125
190
  Use `--print-plan` when you want to preview the fully resolved starter without side effects:
126
191
 
127
192
  ```bash
128
193
  fluo new my-app --shape application --runtime node --platform fastify --print-plan
194
+ fluo new my-react-app --starter react-vite-ssr --print-plan
129
195
  fluo new my-service --shape microservice --transport tcp --print-plan
130
196
  fluo new my-mixed-app --shape mixed --print-plan
131
197
  ```
132
198
 
133
- Plan preview mode resolves the same project name, shape, runtime, platform, transport, tooling preset, package manager, install choice, and git choice as a real scaffold. It prints the selected starter recipe and dependency sets, then exits without creating files, installing dependencies, or initializing a git repository.
199
+ Plan preview mode resolves the same named starter, project name, shape, runtime, platform, transport, tooling preset, package manager, install choice, and git choice as a real scaffold. It prints both the selected starter and recipe plus their dependency sets, then exits without creating files, installing dependencies, or initializing a git repository.
134
200
 
135
- For a docs-level table that separates the shipped starter matrix (Node.js Fastify/Express/raw Node.js HTTP, Bun, Deno, Cloudflare Workers, TCP/Redis Streams/NATS/Kafka/RabbitMQ/MQTT/gRPC microservices, plus mixed) from the remaining broader adapter ecosystem, see the [fluo new support matrix](../../docs/reference/fluo-new-support-matrix.md). Package-level integrations such as `@fluojs/redis` remain part of the broader ecosystem, but they are not extra `fluo new --transport` starter flags.
201
+ For a docs-level table that separates the shipped starter matrix (standard Node.js Fastify/Express/raw Node.js HTTP, React SSR + Vite on Node.js + Fastify, Bun, Deno, Cloudflare Workers, TCP/Redis Streams/NATS/Kafka/RabbitMQ/MQTT/gRPC microservices, plus mixed) from the remaining broader adapter ecosystem, see the [fluo new support matrix](../../docs/reference/fluo-new-support-matrix.md). Package-level integrations such as `@fluojs/redis` remain part of the broader ecosystem, but they are not extra `fluo new --transport` starter flags.
136
202
 
137
203
  ### 2. Generate a feature
138
204
  Generate a feature slice; some schematics auto-register in the module, while others are files-only and must be wired manually.
@@ -196,14 +262,14 @@ fluo dev --studio --dry-run
196
262
 
197
263
  The CLI starts a local Studio sidecar, prints a tokenized URL, keeps restart lifecycle events flowing through the sidecar, and injects an explicit Studio config into the Node app child before the app imports `@fluojs/runtime`. Studio live mode requires the fluo-owned Node restart runner; `fluo dev --studio` rejects `--raw-watch`, `--runner native`, and `FLUO_DEV_RUNNER=native` so lifecycle events cannot be split from the CLI restart boundary. The sidecar serves the packaged `@fluojs/studio/viewer` React app when that optional package is installed. Runtime package source never reads `process.env` directly; it publishes live graph/routes/request/timing/diagnostic events only when CLI-injected Studio config is present.
198
264
 
199
- Security defaults are local-only: the sidecar binds `127.0.0.1`, runtime ingestion and browser state/SSE APIs require generated tokens, CORS is not enabled by default, and request bodies are not captured by default.
265
+ Security defaults are local-only: the sidecar binds `127.0.0.1`, runtime ingestion and browser state/SSE APIs require generated tokens, CORS is not enabled by default, and request bodies are not captured by default. The sidecar settles ingestion requests with a bounded error completion when a local client closes the socket after sending only a partial request body, so a malformed local client cannot hang sidecar work indefinitely. When `StudioSidecar.close()` starts while an authenticated ingestion body is still incomplete, the sidecar closes only its active ingestion sockets, ends tracked SSE responses through the existing close path, and shares one deterministic teardown across repeated or concurrent close calls. Completed ordinary requests are not part of that active-ingestion ownership set, and a client that remains open with a partial body cannot keep CLI shutdown pending indefinitely.
200
266
 
201
267
  Runtime support for the MVP is explicit:
202
268
 
203
269
  | Runtime target | `fluo dev --studio` status |
204
270
  | --- | --- |
205
271
  | Node dev runner | Full support target. |
206
- | Bun | Not enabled for this MVP; `fluo dev --studio` rejects Bun projects until a dedicated bridge is implemented and verified. |
272
+ | Bun | Not enabled for this MVP; `fluo dev --studio` rejects Bun projects until a dedicated bridge is implemented and verified. Export Studio-compatible static artifacts with `fluo inspect <module-path> --json --output <path>` or `fluo inspect <module-path> --report --output <path>` instead. |
207
273
  | Deno | Not enabled for this MVP; `fluo dev --studio` rejects Deno projects until a dedicated bridge is implemented and verified. |
208
274
  | Cloudflare Workers | Unsupported for this MVP unless a worker bridge is added and tested. |
209
275
 
@@ -225,7 +291,7 @@ FLUO_VERBOSE=1 fluo dev
225
291
  fluo build --reporter silent
226
292
  ```
227
293
 
228
- Runtime application logs are configured separately through `ApplicationLogger`, for example `createConsoleApplicationLogger({ mode: 'minimal', level: 'warn' })` or `createJsonApplicationLogger()` from `@fluojs/runtime/node`.
294
+ Runtime application logs are configured separately through `ApplicationLogger`, for example `createConsoleApplicationLogger({ mode: 'minimal', level: 'warn' })` or `createJsonApplicationLogger()` from `@fluojs/platform-nodejs`.
229
295
 
230
296
  Use `fluo add <package>` for first-party package installation shortcuts and `fluo upgrade` for CLI/latest-version and migration guidance:
231
297
 
@@ -245,17 +311,28 @@ fluo migrate ./src --json
245
311
  # Apply transformations
246
312
  fluo migrate ./src --apply
247
313
  fluo migrate ./src --apply --json
248
- fluo migrate ./src --only imports,inject-params
249
- fluo migrate ./src --skip tests
314
+ fluo migrate ./src --only imports,injectable
315
+ fluo migrate ./src --skip testing
250
316
  ```
251
317
 
318
+ The canonical `--only` and `--skip` tokens are `imports`, `inject-params`, `scope`, `bootstrap`, `tests`, and `tsconfig`. The legacy `injectable` and `testing` tokens remain accepted aliases for `inject-params` and `tests`.
319
+
252
320
  Use `--json` when CI jobs, dashboards, or migration reports need a stable machine-readable result. Human output remains the default. JSON mode writes only the structured report to stdout on success, while parser errors and invalid flag combinations still write their message to stderr and return exit code `1` without partial JSON output. The report includes `mode` (`dry-run` or `apply`), `dryRun`, `apply`, enabled `transforms`, `scannedFiles`, `changedFiles`, aggregate `warningCount`, and per-file metadata with `filePath`, `changed`, `appliedTransforms`, `warningCount`, and warnings including category labels and source line numbers.
253
321
 
254
322
  Review every warning before rerunning with `--apply`. Warnings are manual follow-up items rather than permission for an automatic rewrite to be accepted blindly; use the [NestJS migration guide](../../docs/getting-started/migrate-from-nestjs.md) as the post-codemod checklist for each warning category.
255
323
 
324
+ Adapter-independent transforms (`imports`, `injectable`, `scope`, `testing`, and `tsconfig`) run without an HTTP adapter. Bootstrap rewrites never infer a platform: without a selected platform, the codemod retains `NestFactory.create(AppModule)` and its `listen(port)` call and emits a required adapter-selection warning. The only automatic bootstrap rewrite requires explicit `--platform express` and exactly one numeric-literal single-argument `app.listen(port)`. Host, callback, string, environment-derived, and multiple-`listen` forms remain untouched with a warning for manual migration. Install `@fluojs/platform-express` and `express` before compiling the migrated application:
325
+
326
+ ```bash
327
+ fluo migrate ./src --apply --platform express
328
+
329
+ # Leave bootstrap unchanged while applying only adapter-independent transforms
330
+ fluo migrate ./src --apply --only imports,injectable,scope,testing,tsconfig
331
+ ```
332
+
256
333
  **Key Transformations:**
257
334
  - Rewrites imports from `@nestjs/common` to `@fluojs/core` or `@fluojs/http`.
258
- - Rewrites bootstrap patterns and folds supported `listen(port)` calls into fluo runtime startup conventions.
335
+ - Rewrites bootstrap patterns only after explicit platform selection and folds supported `listen(port)` calls into fluo runtime startup conventions.
259
336
  - Migrates constructor parameter `@Inject(...)` usage into fluo-compatible dependency declarations.
260
337
  - Removes `@Injectable()` and maps scopes to `@Scope()`.
261
338
  - Migrates test templates toward `@fluojs/testing` helpers where the codemod can do so safely.
@@ -269,7 +346,7 @@ Export your application structure and troubleshoot initialization issues without
269
346
  fluo inspect ./src/app.module.ts --mermaid
270
347
 
271
348
  # Export snapshot for @fluojs/studio
272
- fluo inspect ./src/app.module.ts --json > snapshot.json
349
+ fluo inspect ./src/app.module.ts --format json > snapshot.json
273
350
 
274
351
  # Write the same JSON snapshot to a CI artifact path without shell redirection
275
352
  fluo inspect ./src/app.module.ts --json --output artifacts/inspect-snapshot.json
@@ -284,7 +361,16 @@ fluo inspect ./src/app.module.ts --report --output artifacts/inspect-report.json
284
361
  fluo inspect ./src/app.module.ts --export AdminModule --json
285
362
  ```
286
363
 
287
- The runtime produces the inspection snapshot. `fluo inspect` accepts generated TypeScript source modules such as `./src/app.ts` or `./src/app.module.ts` through an explicit TypeScript loader boundary, while existing `.js` and `.mjs` module paths continue to load through native Node.js ESM. The CLI owns inspect orchestration, JSON serialization, report wrapping, and `--output <path>` artifact writes; Studio owns snapshot parsing, filtering, connection inspection, viewer rendering, and Mermaid graph semantics. `fluo inspect` serializes the snapshot as JSON by default when no output mode flag is provided, and `fluo inspect --mermaid` delegates snapshot-to-Mermaid rendering to the optional `@fluojs/studio` contract. `--export <name>` selects the module export to bootstrap and defaults to `AppModule`; `--timing` records bootstrap timing diagnostics next to the JSON snapshot output, including when `--timing` is provided without an explicit `--json` flag, and `--report` wraps the runtime-produced snapshot with a stable summary for CI/support triage. `--timing` cannot be combined with Mermaid output. `--output <path>` writes the selected inspect payload to an explicit artifact path instead of stdout; it does not make the inspected application writable or change module graph state beyond the normal bootstrap/close cycle. Install Studio in the project that runs the command when you need Mermaid output:
364
+ `--format json` is explicitly equivalent to `--json`: either writes exactly one JSON document to stdout while runtime diagnostics go to stderr, and any other `--format` value is rejected.
365
+
366
+ The runtime produces the inspection snapshot. `fluo inspect` accepts generated TypeScript source modules such as `./src/app.ts` or `./src/app.module.ts` through an explicit TypeScript loader boundary, while existing `.js` and `.mjs` module paths continue to load through native Node.js ESM. The CLI bootstraps an adapterless application so the authoritative HTTP dispatcher descriptors are available, then adds the runtime-owned `routes` projection to JSON, timing envelopes, and report snapshots. The CLI owns inspect orchestration, JSON serialization, report wrapping, and `--output <path>` artifact writes; Studio owns snapshot parsing, filtering, connection inspection, viewer rendering, and Mermaid graph semantics. `fluo inspect` serializes the snapshot as JSON by default when no output mode flag is provided, and `fluo inspect --mermaid` delegates snapshot-to-Mermaid rendering to the optional `@fluojs/studio` contract. `--export <name>` selects the module export to bootstrap and defaults to `AppModule`; `--timing` records bootstrap timing diagnostics next to the JSON snapshot output, including when `--timing` is provided without an explicit `--json` flag, and `--report` wraps the runtime-produced snapshot with a stable summary for CI/support triage. `--timing` cannot be combined with Mermaid output. `--output <path>` writes the selected inspect payload to an explicit artifact path instead of stdout; it does not make the inspected application writable or change module graph state beyond the normal bootstrap/close cycle.
367
+
368
+ Each `routes[]` entry contains `id`, `kind`, `method`, effective `path`, optional effective `version`,
369
+ parameter names in `params`, and the originating `module`, `controller`, and `handler`. React
370
+ `@Path(...)` handlers use `kind: 'react-page'`; ordinary HTTP handlers use `kind: 'http'`. The
371
+ artifact never contains parameter values, request bodies, cookies, headers, or query values, and the
372
+ route projection does not participate in matching, conflict detection, or dispatch. Install Studio
373
+ in the project that runs the command when you need Mermaid output:
288
374
 
289
375
  ```bash
290
376
  pnpm add -D @fluojs/studio
@@ -292,6 +378,79 @@ pnpm add -D @fluojs/studio
292
378
 
293
379
  If Studio is missing, CI and other non-interactive runs fail fast with install guidance instead of prompting or running a package manager. Interactive runs may ask whether you want to install Studio, but `fluo inspect` does not run installs unless an explicit install flow is implemented and approved.
294
380
 
381
+ ### React Page Type Generation
382
+
383
+ Generate application-owned, path-only React page types and absolute href builders from the
384
+ bootstrap-resolved route catalog:
385
+
386
+ ```bash
387
+ fluo typegen ./src/app.ts --output ./src/generated/react-pages.ts
388
+ fluo typegen ./src/admin.ts --export AdminModule --output ./src/generated/admin-pages.ts
389
+ fluo typegen ./src/app.ts --output ./src/generated/react-pages.ts --check
390
+ fluo typegen ./src/app.ts --output ./src/generated/react-pages.ts --watch
391
+ ```
392
+
393
+ `--export` defaults to `AppModule`. The command loads TypeScript source through the CLI loader,
394
+ bootstraps the application, reads `app.dispatcher.describeRoutes()`, calls
395
+ `createReactPageCatalog(...)` and `generateReactPageTypes(...)`, then closes the application. Output
396
+ paths are resolved from the current working directory. A missing file is reported as `CREATE`, stale
397
+ content as `UPDATE`, and byte-identical content as `UNCHANGED`. Writes publish one complete temporary
398
+ file with an atomic rename, and `UNCHANGED` never rewrites the target.
399
+
400
+ Default generation evaluates the application and matching tooling namespaces in one short-lived
401
+ child process, waits for that process to exit, and only then checks or publishes the result. Repeated
402
+ watch generations therefore do not retain application module graphs or TypeScript loader resources
403
+ in the watcher process. Programmatic callers that provide
404
+ `TypegenCommandRuntimeOptions.loadReactTypegenModules` intentionally keep generation in the caller
405
+ process; the returned namespaces remain authoritative for TypeScript, `.js`, and `.mjs` inputs.
406
+
407
+ `--check` performs the same authoritative bootstrap and generation but never writes the target. It
408
+ compares exact bytes and reports one stable status. `UNCHANGED` goes to stdout with exit code `0`;
409
+ `MISSING`, `STALE`, `MALFORMED`, and `UNSUPPORTED_VERSION` go to stderr with exit codes `2`, `3`, `4`,
410
+ and `5`. A current-version target must be one complete canonical generated body: syntax or structural
411
+ corruption is `MALFORMED`, while a complete artifact from an older catalog is `STALE`. Argument,
412
+ bootstrap, generation, filesystem, and other command failures use exit code `1`. The root package
413
+ exports `TYPEGEN_EXIT_CODES` for programmatic callers.
414
+
415
+ `--watch` is the bounded development integration. The CLI installs the recursive application-module
416
+ watcher before startup generation. It prints `WATCHING <directory>` only after that generation and
417
+ one coalesced rerun for any changes observed while it ran have completed successfully. Filesystem
418
+ bursts after readiness are coalesced for 100 ms, generations are serialized, and events for the
419
+ output or its temporary files are ignored. Each generation evaluates a current application module
420
+ graph, including changed native `.js` and `.mjs` dependencies, before the authoritative bootstrap.
421
+ A regeneration failure prints `ERROR <output>: <message>`, preserves the last valid artifact, and
422
+ waits for a later change. A watcher failure exits with code `1` after cleanup. Every source event
423
+ received while a generation or its owned artifact commit is active invalidates that work; its output
424
+ cannot publish before the coalesced successor completes. `SIGINT` and `SIGTERM` close the watcher,
425
+ remove signal handlers, cancel the active owned generation (a child process or caller-process
426
+ bootstrap), and abort its owned artifact commit before either can publish. Caller-process
427
+ cancellation waits for asynchronous bootstrap and application close to settle before watch exits
428
+ with code `0`; a child that does not exit after `SIGTERM` is force-killed after the bounded grace
429
+ period.
430
+ Files outside the module directory are intentionally outside this watch boundary; run the command
431
+ again or choose a module path at the intended source root instead of expecting source scanning or a
432
+ second route discovery system.
433
+
434
+ The generated `reactPageRoutes` object keys routes by stable catalog `id`. Its dynamic `href(...)`,
435
+ `link(...)`, `push(...)`, and `replace(...)` methods require all path params and URI-encode each value;
436
+ static methods accept no params. Spread `route.link(params)` into the existing real-anchor `Link`, or
437
+ pass the existing `ReactRouter` to `route.push(router, params)` / `route.replace(router, params)`:
438
+
439
+ ```tsx
440
+ const productRoute = reactPageRoutes['GET /products/:productId ProductRouter show'];
441
+
442
+ <Link {...productRoute.link({ productId })}>Product</Link>;
443
+ productRoute.push(router, { productId });
444
+ productRoute.replace(router, { productId });
445
+ ```
446
+
447
+ These generated methods resolve to ordinary absolute href strings before the existing HTTP-first
448
+ client APIs run. They do not add a runtime route table, matcher, relative-route model, or SPA
449
+ navigation. Existing `href(...)`, `Link href`, and router string/`URL` calls remain supported.
450
+ Versioned routes fail explicitly because the catalog cannot distinguish URI versioning from header,
451
+ media-type, or custom version strategies. See the
452
+ [@fluojs/react path-only typegen contract](../react/README.md#path-only-page-type-generation).
453
+
295
454
  ## Public API
296
455
 
297
456
  The package can be used programmatically to trigger CLI actions from within other tools.
@@ -302,7 +461,7 @@ The package can be used programmatically to trigger CLI actions from within othe
302
461
  | `CliRuntimeOptions` | Type for `runCli(...)` runtime overrides such as streams, cwd, environment, registry metadata, and update-check hooks. |
303
462
  | `newUsage()` | Returns the current `fluo new` usage text for help surfaces and tests. |
304
463
  | `runNewCommand(argv, options?)` | Programmatic access to the project scaffolding logic. |
305
- | `NewCommandRuntimeOptions` | Type for `runNewCommand(...)` runtime overrides such as prompts, filesystem writes, dependency installation, and git initialization. |
464
+ | `NewCommandRuntimeOptions` | Type for `runNewCommand(...)` runtime overrides such as prompts, filesystem writes, dependency installation, and git initialization; `runCli(...)` also accepts these overrides when it dispatches `new` or `create`. Monorepo-local starter dependency overrides are internal sandbox harness details, not part of this public type. |
306
465
  | `CliPromptCancelledError` | Stable sentinel that caller-supplied prompt hooks can throw to report normal cancellation. |
307
466
  | `runGenerateCommand(kind, name, baseDirectory, options?)` | Programmatic access to the built-in schematic generator and module auto-registration planner. |
308
467
  | `GenerateOptions` | Type for programmatic generator options. |
@@ -312,10 +471,14 @@ The package can be used programmatically to trigger CLI actions from within othe
312
471
  | `GeneratorKind` | Union type of all supported generator types (e.g., `'controller'`, `'service'`). |
313
472
  | `ModuleRegistration` | Type describing controller, provider, or middleware module wiring metadata from generator runs. |
314
473
  | `inspectUsage()` | Returns the current `fluo inspect` usage text for help surfaces and tests. |
315
- | `runInspectCommand(argv, options?)` | Programmatic access to inspect orchestration, JSON/report emission, and Studio Mermaid delegation. |
474
+ | `runInspectCommand(argv, options?)` | Programmatic access to inspect orchestration, compiled route JSON/report emission, and Studio Mermaid delegation. |
316
475
  | `InspectCommandRuntimeOptions` | Type for `runInspectCommand(...)` and `runCli(...)` inspect runtime overrides such as cwd, streams, prompts, and Studio renderer loading. |
476
+ | `typegenUsage()` | Returns the current `fluo typegen` usage text for help surfaces and tests. |
477
+ | `TYPEGEN_EXIT_CODES` | Stable `SUCCESS`, `ERROR`, `MISSING`, `STALE`, `MALFORMED`, and `UNSUPPORTED_VERSION` process codes used by typegen automation. |
478
+ | `runTypegenCommand(argv, options?)` | Programmatic access to bootstrap-resolved React page generation, non-mutating checks, and bounded watch mode. |
479
+ | `TypegenCommandRuntimeOptions` | Type for `runTypegenCommand(...)` and `runCli(...)` typegen runtime overrides such as cwd, streams, and tooling module loading. Supplying `loadReactTypegenModules` selects caller-process generation with those namespaces; omitting it uses short-lived generation children. |
317
480
 
318
- Programmatic entry points preserve caller process ownership. `runCli(...)`, `runNewCommand(...)`, and `runInspectCommand(...)` return numeric exit codes instead of calling `process.exit(...)`; prompt cancellation resolves as exit code `0` through the command runner, and setup actions such as dependency installation or git initialization only run when the resolved `fluo new` options request them. `runGenerateCommand(...)` returns a structured `GenerateResult`; pass `dryRun: true` to preview generated file and module-wiring actions without writing files. Caller-supplied prompt hooks can throw `CliPromptCancelledError` from the public package entrypoint to express normal cancellation without depending on CLI-internal files.
481
+ Programmatic entry points preserve caller process ownership. `runCli(...)`, `runNewCommand(...)`, `runInspectCommand(...)`, and `runTypegenCommand(...)` return numeric exit codes instead of calling `process.exit(...)`; typegen callers can compare those results with `TYPEGEN_EXIT_CODES`. Prompt cancellation resolves as exit code `0` through the command runner, and setup actions such as dependency installation or git initialization only run when the resolved `fluo new` options request them. `runGenerateCommand(...)` returns a structured `GenerateResult`; pass `dryRun: true` to preview generated file and module-wiring actions without writing files. Caller-supplied prompt hooks can throw `CliPromptCancelledError` from the public package entrypoint to express normal cancellation without depending on CLI-internal files.
319
482
 
320
483
  ## Related Packages
321
484
 
@@ -330,6 +493,7 @@ Programmatic entry points preserve caller process ownership. `runCli(...)`, `run
330
493
  - [cli.ts](./src/cli.ts) - Command dispatcher and argument parsing.
331
494
  - [commands/new.ts](./src/commands/new.ts) - Project scaffolding implementation.
332
495
  - [commands/inspect.ts](./src/commands/inspect.ts) - Runtime inspection export modes and Studio delegation.
496
+ - [commands/typegen.ts](./src/commands/typegen.ts) - React page catalog bootstrap and deterministic path-only artifact writes.
333
497
  - [commands/migrate.ts](./src/commands/migrate.ts) - Decorator codemods, JSON reporting, and transform filters.
334
498
  - [commands/package-workflow.ts](./src/commands/package-workflow.ts) - `fluo add` and `fluo upgrade` workflows.
335
499
  - [commands/scripts.ts](./src/commands/scripts.ts) - `dev`, `build`, and `start` lifecycle command boundaries.
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { type InspectCommandRuntimeOptions } from './commands/inspect.js';
2
- import { type NewCommandRuntimeOptions } from './commands/new.js';
1
+ import type { InspectCommandRuntimeOptions } from './commands/inspect.js';
2
+ import type { NewCommandRuntimeOptions } from './commands/new.js';
3
+ import type { TypegenCommandRuntimeOptions } from './commands/typegen.js';
3
4
  import type { startStudioSidecar } from './studio/sidecar.js';
4
5
  import { type CliUpdateCheckRuntimeOptions } from './update-check.js';
5
6
  type CliStream = {
@@ -50,8 +51,8 @@ export interface CliRuntimeOptions {
50
51
  *
51
52
  * @param argv Argument vector to execute. Defaults to the current process arguments without the node/bin prefix.
52
53
  * @param runtime Optional runtime overrides shared by the top-level dispatcher and delegated commands.
53
- * @returns `0` when the command completes successfully, otherwise `1` after writing the error message to `stderr`.
54
+ * @returns `0` when the command completes successfully, otherwise the delegated command exit code.
54
55
  */
55
- export declare function runCli(argv?: string[], runtime?: CliRuntimeOptions & NewCommandRuntimeOptions & InspectCommandRuntimeOptions): Promise<number>;
56
+ export declare function runCli(argv?: string[], runtime?: CliRuntimeOptions & NewCommandRuntimeOptions & InspectCommandRuntimeOptions & TypegenCommandRuntimeOptions): Promise<number>;
56
57
  export {};
57
58
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,4BAA4B,EAAmC,MAAM,uBAAuB,CAAC;AAE3G,OAAO,EAAE,KAAK,wBAAwB,EAA2B,MAAM,mBAAmB,CAAC;AAI3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAI9D,OAAO,EAAE,KAAK,4BAA4B,EAA6C,MAAM,mBAAmB,CAAC;AAEjH,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;IACrF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACzL,kBAAkB,CAAC,EAAE,OAAO,kBAAkB,CAAC;IAC/C,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,GAAG,4BAA4B,CAAC;CACpD;AA4ZD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,iBAAiB,GAAG,wBAAwB,GAAG,4BAAiC,GACxF,OAAO,CAAC,MAAM,CAAC,CAuNjB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,KAAK,4BAA4B,EAA6C,MAAM,mBAAmB,CAAC;AAGjH,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;IACrF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACzL,kBAAkB,CAAC,EAAE,OAAO,kBAAkB,CAAC;IAC/C,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,GAAG,4BAA4B,CAAC;CACpD;AAqaD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,iBAAiB,GAAG,wBAAwB,GAAG,4BAA4B,GAAG,4BAAiC,GACvH,OAAO,CAAC,MAAM,CAAC,CA6PjB"}