@fluojs/cli 1.1.0 → 2.0.1

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 (44) hide show
  1. package/README.ko.md +16 -3
  2. package/README.md +16 -3
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +4 -3
  5. package/dist/commands/generate.d.ts +1 -49
  6. package/dist/commands/generate.d.ts.map +1 -1
  7. package/dist/commands/generate.js +1 -214
  8. package/dist/commands/inspect.d.ts +0 -6
  9. package/dist/commands/inspect.d.ts.map +1 -1
  10. package/dist/commands/inspect.js +1 -48
  11. package/dist/commands/new.d.ts +0 -6
  12. package/dist/commands/new.d.ts.map +1 -1
  13. package/dist/commands/new.js +14 -88
  14. package/dist/commands/scripts.d.ts +1 -1
  15. package/dist/commands/scripts.d.ts.map +1 -1
  16. package/dist/commands/scripts.js +11 -5
  17. package/dist/dev-runner/node-restart-runner.d.ts +6 -0
  18. package/dist/dev-runner/node-restart-runner.d.ts.map +1 -1
  19. package/dist/dev-runner/node-restart-runner.js +10 -6
  20. package/dist/generate-command.d.ts +50 -0
  21. package/dist/generate-command.d.ts.map +1 -0
  22. package/dist/generate-command.js +214 -0
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +3 -3
  26. package/dist/new/scaffold.d.ts.map +1 -1
  27. package/dist/new/scaffold.js +115 -23
  28. package/dist/new/types.d.ts +0 -2
  29. package/dist/new/types.d.ts.map +1 -1
  30. package/dist/public-generate.d.ts +2 -0
  31. package/dist/public-generate.d.ts.map +1 -0
  32. package/dist/public-generate.js +1 -0
  33. package/dist/public-inspect.d.ts +13 -0
  34. package/dist/public-inspect.d.ts.map +1 -0
  35. package/dist/public-inspect.js +16 -0
  36. package/dist/public-new.d.ts +13 -0
  37. package/dist/public-new.d.ts.map +1 -0
  38. package/dist/public-new.js +16 -0
  39. package/dist/studio/sidecar.d.ts.map +1 -1
  40. package/dist/studio/sidecar.js +71 -5
  41. package/dist/usage.d.ts +13 -0
  42. package/dist/usage.d.ts.map +1 -0
  43. package/dist/usage.js +131 -0
  44. package/package.json +3 -3
package/README.ko.md CHANGED
@@ -31,6 +31,7 @@ pnpm dlx @fluojs/cli new my-app
31
31
  ## 릴리스 계약
32
32
 
33
33
  - `@fluojs/cli`는 intended publish surface에 포함되는 공개 패키지입니다.
34
+ - `@fluojs/cli`는 Node.js `>=20.0.0`을 요구합니다. 생성된 Bun, Deno, Cloudflare Workers starter가 비 Node runtime을 대상으로 할 수는 있지만 CLI process 자체는 Node.js에서 실행됩니다.
34
35
  - 지원되는 설치 경로는 전역 패키지(`npm install -g @fluojs/cli`, `pnpm add -g @fluojs/cli`, `bun add -g @fluojs/cli`, `yarn global add @fluojs/cli`)와 무설치 실행 경로(`pnpm dlx @fluojs/cli ...`)입니다.
35
36
  - 배포되는 `fluo` bin은 `package.json`에 선언된 `./bin/fluo.mjs` wrapper이며, 이 wrapper가 dist 빌드 CLI 엔트리포인트인 `../dist/cli.js`를 로드합니다.
36
37
 
@@ -112,7 +113,7 @@ fluo new my-grpc-service --shape microservice --transport grpc --runtime node --
112
113
 
113
114
  지원되는 `--shape microservice --transport` 스타터 값은 정확히 `tcp`, `redis-streams`, `nats`, `kafka`, `rabbitmq`, `mqtt`, `grpc`입니다. 유지보수되는 Redis 기반 스타터가 필요하면 `redis-streams`를 사용하고, 더 넓은 Redis 통합 패턴이 필요하면 스캐폴딩 후 `@fluojs/redis`를 수동으로 추가하세요.
114
115
 
115
- NATS/Kafka/RabbitMQ 스타터 계약은 외부 broker와 caller-owned client library 의존성을 숨기지 않고 명시적으로 유지합니다. 생성된 프로젝트는 `src/app.ts`에서 `nats` + `JSONCodec()`, `kafkajs` producer/consumer collaborator, `amqplib` publisher/consumer collaborator를 직접 연결하므로, 기본 fluo 패키지가 그 의존성을 감춘 것처럼 가장하지 않는 runnable starter 계약이 됩니다. 해당 broker client는 생성된 transport wrapper가 Fluo lifecycle에서 listen/send/emit을 시작할 때 lazy하게 생성합니다. 따라서 `fluo inspect`, 테스트, static tooling이 `src/app.ts`를 import하는 것만으로는 broker에 연결하거나 lifecycle이 teardown을 소유하기 전에 외부 리소스를 열지 않습니다.
116
+ NATS/Kafka/RabbitMQ 스타터 계약은 외부 broker와 caller-owned client library 의존성을 숨기지 않고 명시적으로 유지합니다. 생성된 프로젝트는 `src/app.ts`에서 `nats` + `JSONCodec()`, `kafkajs` producer/consumer collaborator, `amqplib` publisher/consumer collaborator를 직접 연결하므로, 기본 fluo 패키지가 그 의존성을 감춘 것처럼 가장하지 않는 runnable starter 계약이 됩니다. 해당 broker client는 생성된 transport wrapper가 Fluo lifecycle에서 listen/send/emit을 시작할 때 lazy하게 생성합니다. 따라서 `fluo inspect`, 테스트, static tooling이 `src/app.ts`를 import하는 것만으로는 broker에 연결하거나 lifecycle이 teardown을 소유하기 전에 외부 리소스를 열지 않습니다. 종료 중 delegated transport shutdown이 실패해도 각 wrapper는 소유한 client 종료를 계속 시도합니다. Kafka 연결이 일부만 성공한 경우에는 획득한 client를 disconnect하고, RabbitMQ channel 생성이 실패한 경우에는 획득한 connection을 닫은 뒤 startup error를 다시 던집니다.
116
117
 
117
118
  starter 매트릭스에는 mixed single-package starter도 포함됩니다. 하나의 Fastify HTTP 앱과 attached TCP microservice를 같은 생성 프로젝트 안에 함께 배치합니다.
118
119
 
@@ -122,6 +123,18 @@ fluo new my-mixed-app --shape mixed --transport tcp --runtime node --platform fa
122
123
 
123
124
  `fluo new`가 interactive TTY에서 실행되면 wizard는 기존 flags/config 모델을 그대로 사용합니다. wizard는 프로젝트 이름, shape-first 분기(`application` -> runtime + HTTP platform, `microservice` -> transport), 유지보수 가능한 tooling preset, package manager, 즉시 dependency를 설치할지 여부, git 저장소를 초기화할지 여부를 묻습니다. non-interactive 플래그 경로와 프로그래밍 방식의 `runNewCommand(...)` 호출도 동일한 resolved defaults를 사용합니다.
124
125
 
126
+ 기본적으로 `fluo new my-app`은 `./my-app`에 파일을 씁니다. 프로젝트 이름과 대상 경로가 달라야 하거나 자동화에서 명시적인 디렉터리에 써야 하면 `--target-directory <path>`를 사용하세요:
127
+
128
+ ```bash
129
+ fluo new my-app --target-directory ./apps/api
130
+ ```
131
+
132
+ Scaffold는 기본적으로 비어 있지 않은 대상에서 충돌하는 파일을 덮어쓰지 않습니다. 내용이 다른 생성 파일을 의도적으로 덮어쓰려는 경우에만 `--force`를 추가하세요:
133
+
134
+ ```bash
135
+ fluo new my-app --target-directory ./apps/api --force
136
+ ```
137
+
125
138
  side effect 없이 완전히 resolved starter를 미리 확인하려면 `--print-plan`을 사용하세요:
126
139
 
127
140
  ```bash
@@ -196,7 +209,7 @@ fluo dev --studio --dry-run
196
209
 
197
210
  CLI는 local Studio sidecar를 시작하고, tokenized URL을 출력하며, restart lifecycle event를 sidecar로 계속 전달하고, 앱이 `@fluojs/runtime`을 import하기 전에 명시적인 Studio config를 Node 앱 child에 주입합니다. Studio live mode는 fluo가 소유한 Node restart runner를 요구합니다. 따라서 lifecycle event가 CLI restart boundary와 분리되지 않도록 `fluo dev --studio`는 `--raw-watch`, `--runner native`, `FLUO_DEV_RUNNER=native`를 거부합니다. Optional package인 `@fluojs/studio`가 설치되어 있으면 sidecar는 패키징된 `@fluojs/studio/viewer` React app을 제공합니다. Runtime package source는 `process.env`를 직접 읽지 않으며, CLI가 주입한 Studio config가 있을 때만 live graph/routes/request/timing/diagnostic event를 전송합니다.
198
211
 
199
- 보안 기본값은 local-only입니다. Sidecar는 `127.0.0.1`에 bind되고, runtime ingestion 및 browser state/SSE API는 generated token을 요구하며, CORS는 기본적으로 활성화하지 않고, request body는 기본적으로 수집하지 않습니다.
212
+ 보안 기본값은 local-only입니다. Sidecar는 `127.0.0.1`에 bind되고, runtime ingestion 및 browser state/SSE API는 generated token을 요구하며, CORS는 기본적으로 활성화하지 않고, request body는 기본적으로 수집하지 않습니다. Local client가 partial request body만 보내고 socket을 닫으면 sidecar는 bounded error completion으로 ingestion 요청을 settle하므로, malformed local client가 sidecar 작업을 무기한 대기시킬 수 없습니다.
200
213
 
201
214
  MVP runtime support는 명시적으로 제한됩니다.
202
215
 
@@ -302,7 +315,7 @@ Studio가 없으면 CI와 non-interactive 실행은 prompt나 package manager
302
315
  | `CliRuntimeOptions` | stream, cwd, environment, registry metadata, update-check hook 같은 `runCli(...)` runtime override 타입입니다. |
303
316
  | `newUsage()` | help surface와 test에서 사용하는 현재 `fluo new` usage text를 반환합니다. |
304
317
  | `runNewCommand(argv, options?)` | 프로젝트 스캐폴딩 로직에 대한 프로그래밍적 접근을 제공합니다. |
305
- | `NewCommandRuntimeOptions` | prompt, filesystem write, dependency install, git initialization 같은 `runNewCommand(...)` runtime override 타입입니다. |
318
+ | `NewCommandRuntimeOptions` | prompt, filesystem write, dependency install, git initialization 같은 `runNewCommand(...)` runtime override 타입입니다. `runCli(...)`도 `new` 또는 `create`로 dispatch할 때 이 override를 받습니다. Monorepo-local starter dependency override는 내부 sandbox harness 세부사항이며 이 공개 타입의 일부가 아닙니다. |
306
319
  | `CliPromptCancelledError` | 호출자가 제공한 prompt hook이 정상 취소를 알리기 위해 throw할 수 있는 안정적인 sentinel입니다. |
307
320
  | `runGenerateCommand(kind, name, baseDirectory, options?)` | built-in schematic generator와 module auto-registration planner에 대한 프로그래밍적 접근을 제공합니다. |
308
321
  | `GenerateOptions` | 프로그래밍 방식 generator 옵션 타입입니다. |
package/README.md CHANGED
@@ -31,6 +31,7 @@ pnpm dlx @fluojs/cli new my-app
31
31
  ## Release Contract
32
32
 
33
33
  - `@fluojs/cli` is a public package in the intended publish surface.
34
+ - `@fluojs/cli` requires Node.js `>=20.0.0`; generated Bun, Deno, and Cloudflare Workers starters may target non-Node runtimes, but the CLI process itself runs on Node.js.
34
35
  - 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
36
  - 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
37
 
@@ -112,7 +113,7 @@ fluo new my-grpc-service --shape microservice --transport grpc --runtime node --
112
113
 
113
114
  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
115
 
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.
116
+ 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
117
 
117
118
  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
119
 
@@ -122,6 +123,18 @@ fluo new my-mixed-app --shape mixed --transport tcp --runtime node --platform fa
122
123
 
123
124
  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.
124
125
 
126
+ 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:
127
+
128
+ ```bash
129
+ fluo new my-app --target-directory ./apps/api
130
+ ```
131
+
132
+ 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:
133
+
134
+ ```bash
135
+ fluo new my-app --target-directory ./apps/api --force
136
+ ```
137
+
125
138
  Use `--print-plan` when you want to preview the fully resolved starter without side effects:
126
139
 
127
140
  ```bash
@@ -196,7 +209,7 @@ fluo dev --studio --dry-run
196
209
 
197
210
  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
211
 
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.
212
+ 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.
200
213
 
201
214
  Runtime support for the MVP is explicit:
202
215
 
@@ -302,7 +315,7 @@ The package can be used programmatically to trigger CLI actions from within othe
302
315
  | `CliRuntimeOptions` | Type for `runCli(...)` runtime overrides such as streams, cwd, environment, registry metadata, and update-check hooks. |
303
316
  | `newUsage()` | Returns the current `fluo new` usage text for help surfaces and tests. |
304
317
  | `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. |
318
+ | `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
319
  | `CliPromptCancelledError` | Stable sentinel that caller-supplied prompt hooks can throw to report normal cancellation. |
307
320
  | `runGenerateCommand(kind, name, baseDirectory, options?)` | Programmatic access to the built-in schematic generator and module auto-registration planner. |
308
321
  | `GenerateOptions` | Type for programmatic generator options. |
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":"AAMA,OAAO,EAAE,KAAK,4BAA4B,EAAqB,MAAM,uBAAuB,CAAC;AAE7F,OAAO,EAAE,KAAK,wBAAwB,EAAiB,MAAM,mBAAmB,CAAC;AAMjF,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;AA4ZD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,iBAAiB,GAAG,wBAAwB,GAAG,4BAAiC,GACxF,OAAO,CAAC,MAAM,CAAC,CAuNjB"}
package/dist/cli.js CHANGED
@@ -1,17 +1,18 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { diagnosticsUsage, runAnalyzeCommand, runDoctorCommand, runInfoCommand } from './commands/diagnostics.js';
5
5
  import { runGenerateCommand } from './commands/generate.js';
6
- import { inspectUsage, runInspectCommand } from './commands/inspect.js';
6
+ import { runInspectCommand } from './commands/inspect.js';
7
7
  import { migrateUsage, runMigrateCommand } from './commands/migrate.js';
8
- import { newUsage, runNewCommand } from './commands/new.js';
8
+ import { runNewCommand } from './commands/new.js';
9
9
  import { addUsage, runAddCommand, runUpgradeCommand, upgradeUsage } from './commands/package-workflow.js';
10
10
  import { runScriptCommand, scriptUsage } from './commands/scripts.js';
11
11
  import { runNodeRestartRunner } from './dev-runner/node-restart-runner.js';
12
12
  import { builtInGeneratorCollection, generatorManifest, generatorOptionSchemas, resolveGeneratorKind } from './generators/manifest.js';
13
13
  import { renderAliasList, renderHelpTable } from './help.js';
14
14
  import { removeUpdateCheckFlags, runCliUpdateCheck } from './update-check.js';
15
+ import { inspectUsage, newUsage } from './usage.js';
15
16
 
16
17
  /**
17
18
  * Runtime dependency overrides for embedding the CLI in tests or higher-level tooling.
@@ -1,50 +1,2 @@
1
- import type { GenerateOptions, GeneratorKind } from '../types.js';
2
- import type { GeneratorManifestEntry } from '../generators/manifest.js';
3
- /** Describes how one generated artifact would interact with the workspace. */
4
- export type GeneratePlanAction = 'create' | 'module-create' | 'module-unchanged' | 'module-update' | 'overwrite' | 'skip' | 'unchanged';
5
- /** One path-level action reported by generate dry-run previews and structured results. */
6
- export type GeneratePlanEntry = {
7
- /** Planned action for this path. */
8
- action: GeneratePlanAction;
9
- /** Absolute path affected by the plan entry. */
10
- path: string;
11
- };
12
- /**
13
- * Structured result returned by {@link runGenerateCommand} for tooling-friendly automation.
14
- *
15
- * `generatedFiles` only includes files whose on-disk content changed during the command.
16
- * `moduleRegistered` reports whether the target schematic participates in automatic module wiring,
17
- * even when the target module file was already up to date.
18
- */
19
- export type GenerateResult = {
20
- generatedFiles: string[];
21
- moduleRegistered: boolean;
22
- modulePath: string | undefined;
23
- nextStepHint: string;
24
- plannedFiles: GeneratePlanEntry[];
25
- wiringBehavior: GeneratorManifestEntry['wiringBehavior'];
26
- };
27
- /**
28
- * Generates one CLI schematic into a source directory and returns structured wiring metadata.
29
- *
30
- * The command keeps generation idempotent where possible: unchanged files are not rewritten, and
31
- * auto-registered schematics reuse an existing module file when it already contains the required import
32
- * and registration entry.
33
- *
34
- * @example
35
- * ```ts
36
- * const result = runGenerateCommand('service', 'Post', './src');
37
- *
38
- * console.log(result.wiringBehavior);
39
- * console.log(result.nextStepHint);
40
- * ```
41
- *
42
- * @param kind Generator kind to execute.
43
- * @param name Resource name supplied by the caller before normalization.
44
- * @param baseDirectory Source directory that should receive the generated domain folder.
45
- * @param options Optional generation flags that control overwrites, request DTO feature placement, and sibling-aware templates.
46
- * @returns Structured file and wiring metadata for the completed generation run.
47
- * @throws {Error} When the resource name is invalid, the generator kind is unknown, or the target module source cannot be updated safely.
48
- */
49
- export declare function runGenerateCommand(kind: GeneratorKind, name: string, baseDirectory: string, options?: GenerateOptions): GenerateResult;
1
+ export { type GeneratePlanAction, type GeneratePlanEntry, type GenerateResult, runGenerateCommand } from '../generate-command.js';
50
2
  //# sourceMappingURL=generate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAkB,MAAM,2BAA2B,CAAC;AAexF,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,eAAe,GAAG,kBAAkB,GAAG,eAAe,GAAG,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAExI,0FAA0F;AAC1F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAyIF;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;CAC1D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAgE1I"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1,214 +1 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { basename, dirname, join, normalize, relative, resolve, sep } from 'node:path';
3
- import { findGeneratorDefinition } from '../generators/manifest.js';
4
- import { ensureModuleImport, generateModuleFiles, registerInModule } from '../generators/module.js';
5
- import { toKebabCase, toPascalCase, toPlural } from '../generators/utils.js';
6
- function writeFileIfChanged(filePath, content) {
7
- if (existsSync(filePath) && readFileSync(filePath, 'utf8') === content) {
8
- return false;
9
- }
10
- writeFileSync(filePath, content, 'utf8');
11
- return true;
12
- }
13
-
14
- /** Describes how one generated artifact would interact with the workspace. */
15
-
16
- /** One path-level action reported by generate dry-run previews and structured results. */
17
-
18
- function planFileWrite(filePath, content, options) {
19
- if (!existsSync(filePath)) {
20
- return {
21
- action: 'create',
22
- path: filePath
23
- };
24
- }
25
- if (!options.force) {
26
- return {
27
- action: 'skip',
28
- path: filePath
29
- };
30
- }
31
- if (readFileSync(filePath, 'utf8') === content) {
32
- return {
33
- action: 'unchanged',
34
- path: filePath
35
- };
36
- }
37
- return {
38
- action: 'overwrite',
39
- path: filePath
40
- };
41
- }
42
- function planModuleWrite(modulePath, content) {
43
- if (!existsSync(modulePath)) {
44
- return {
45
- action: 'module-create',
46
- path: modulePath
47
- };
48
- }
49
- if (readFileSync(modulePath, 'utf8') === content) {
50
- return {
51
- action: 'module-unchanged',
52
- path: modulePath
53
- };
54
- }
55
- return {
56
- action: 'module-update',
57
- path: modulePath
58
- };
59
- }
60
- function createGeneratorOptions(kind, domainDirectory, kebab, options, resolvedBase) {
61
- return {
62
- ...options,
63
- e2eRootModuleImport: options.e2eRootModuleImport ?? (kind === 'e2e' ? resolveE2eRootModuleImport(domainDirectory, resolvedBase) : undefined),
64
- hasRepo: options.hasRepo ?? (kind === 'service' ? existsSync(join(domainDirectory, `${kebab}.repo.ts`)) : undefined),
65
- hasService: options.hasService ?? (kind === 'controller' ? existsSync(join(domainDirectory, `${kebab}.service.ts`)) : undefined)
66
- };
67
- }
68
- function toImportSpecifier(path) {
69
- const normalized = path.split(sep).join('/');
70
- return normalized.startsWith('.') ? normalized : `./${normalized}`;
71
- }
72
- function resolveE2eRootModuleImport(domainDirectory, resolvedBase) {
73
- return toImportSpecifier(relative(domainDirectory, join(resolvedBase, 'app')));
74
- }
75
- function resolveDomainDirectory(kind, resolvedBase, kebab, options) {
76
- if (kind === 'e2e') {
77
- return basename(resolvedBase) === 'src' ? join(dirname(resolvedBase), 'test') : join(resolvedBase, 'test');
78
- }
79
- if (kind === 'request-dto' && options.targetFeature !== undefined) {
80
- const normalizedFeature = options.targetFeature.trim();
81
- const featureKebab = assertValidResourceName(normalizedFeature);
82
- const featureDirectory = /^[A-Z]/u.test(normalizedFeature) ? toPlural(featureKebab) : featureKebab;
83
- return join(resolvedBase, featureDirectory);
84
- }
85
- return join(resolvedBase, toPlural(kebab));
86
- }
87
- function assertValidResourceName(name) {
88
- const kebab = toKebabCase(name);
89
- if (name.trim().length === 0) {
90
- throw new Error('Invalid resource name: name must not be empty.');
91
- }
92
- if (kebab !== normalize(kebab) || kebab.includes('/') || kebab.includes('\\') || kebab.includes('..')) {
93
- throw new Error(`Invalid resource name "${name}": must not contain path separators or traversal sequences.`);
94
- }
95
- if (!/^[a-z0-9][a-z0-9-]*$/.test(kebab)) {
96
- throw new Error(`Invalid resource name "${name}": use letters, numbers, spaces, underscores, or hyphens only.`);
97
- }
98
- return kebab;
99
- }
100
- function resolveModulePath(domainDirectory, name) {
101
- const kebab = toKebabCase(name);
102
- return join(domainDirectory, `${kebab}.module.ts`);
103
- }
104
- function readOrCreateModuleSource(modulePath, name) {
105
- if (existsSync(modulePath)) {
106
- return readFileSync(modulePath, 'utf8');
107
- }
108
- const [moduleFile] = generateModuleFiles(name);
109
- if (!moduleFile) {
110
- throw new Error(`Unable to generate module file for resource "${name}".`);
111
- }
112
- return moduleFile.content;
113
- }
114
- function buildUpdatedModuleSource(moduleSource, arrayKey, className, importPath) {
115
- let source = moduleSource;
116
- source = ensureModuleImport(source, className, importPath);
117
- source = registerInModule(source, arrayKey, className);
118
- return source;
119
- }
120
- function prepareModuleUpdate(domainDirectory, normalizedName, kind, classSuffix, arrayKey) {
121
- const kebab = toKebabCase(normalizedName);
122
- const modulePath = resolveModulePath(domainDirectory, normalizedName);
123
- const className = `${toPascalCase(normalizedName)}${classSuffix}`;
124
- const importPath = `${kebab}.${kind}`;
125
- const moduleSource = readOrCreateModuleSource(modulePath, normalizedName);
126
- return {
127
- modulePath,
128
- source: buildUpdatedModuleSource(moduleSource, arrayKey, className, importPath)
129
- };
130
- }
131
-
132
- /**
133
- * Structured result returned by {@link runGenerateCommand} for tooling-friendly automation.
134
- *
135
- * `generatedFiles` only includes files whose on-disk content changed during the command.
136
- * `moduleRegistered` reports whether the target schematic participates in automatic module wiring,
137
- * even when the target module file was already up to date.
138
- */
139
-
140
- /**
141
- * Generates one CLI schematic into a source directory and returns structured wiring metadata.
142
- *
143
- * The command keeps generation idempotent where possible: unchanged files are not rewritten, and
144
- * auto-registered schematics reuse an existing module file when it already contains the required import
145
- * and registration entry.
146
- *
147
- * @example
148
- * ```ts
149
- * const result = runGenerateCommand('service', 'Post', './src');
150
- *
151
- * console.log(result.wiringBehavior);
152
- * console.log(result.nextStepHint);
153
- * ```
154
- *
155
- * @param kind Generator kind to execute.
156
- * @param name Resource name supplied by the caller before normalization.
157
- * @param baseDirectory Source directory that should receive the generated domain folder.
158
- * @param options Optional generation flags that control overwrites, request DTO feature placement, and sibling-aware templates.
159
- * @returns Structured file and wiring metadata for the completed generation run.
160
- * @throws {Error} When the resource name is invalid, the generator kind is unknown, or the target module source cannot be updated safely.
161
- */
162
- export function runGenerateCommand(kind, name, baseDirectory, options = {}) {
163
- const normalizedName = name.trim();
164
- const kebab = assertValidResourceName(normalizedName);
165
- const generator = findGeneratorDefinition(kind);
166
- const resolvedBase = resolve(baseDirectory);
167
- const domainDirectory = resolveDomainDirectory(kind, resolvedBase, kebab, options);
168
- const generatorOptions = createGeneratorOptions(kind, domainDirectory, kebab, options, resolvedBase);
169
- const files = generator.factory(normalizedName, generatorOptions);
170
- const moduleRegistration = 'moduleRegistration' in generator ? generator.moduleRegistration : undefined;
171
- const moduleUpdate = moduleRegistration ? prepareModuleUpdate(domainDirectory, normalizedName, kind, moduleRegistration.classSuffix, moduleRegistration.arrayKey) : undefined;
172
- const plannedFiles = files.map(file => planFileWrite(join(domainDirectory, file.path), file.content, options));
173
- const modulePlan = moduleUpdate ? planModuleWrite(moduleUpdate.modulePath, moduleUpdate.source) : undefined;
174
- if (options.dryRun) {
175
- return {
176
- generatedFiles: [],
177
- moduleRegistered: moduleUpdate !== undefined,
178
- modulePath: moduleUpdate?.modulePath,
179
- nextStepHint: generator.nextStepHint,
180
- plannedFiles: modulePlan ? [...plannedFiles, modulePlan] : plannedFiles,
181
- wiringBehavior: generator.wiringBehavior
182
- };
183
- }
184
- mkdirSync(domainDirectory, {
185
- recursive: true
186
- });
187
- const writtenPaths = files.map(file => {
188
- const filePath = join(domainDirectory, file.path);
189
- if (!options.force && existsSync(filePath)) {
190
- return null;
191
- }
192
- return writeFileIfChanged(filePath, file.content) ? filePath : null;
193
- }).filter(filePath => filePath !== null);
194
- let moduleRegistered = false;
195
- let resolvedModulePath;
196
- if (moduleUpdate && writeFileIfChanged(moduleUpdate.modulePath, moduleUpdate.source)) {
197
- moduleRegistered = true;
198
- resolvedModulePath = moduleUpdate.modulePath;
199
- if (!writtenPaths.includes(moduleUpdate.modulePath)) {
200
- writtenPaths.push(moduleUpdate.modulePath);
201
- }
202
- } else if (moduleUpdate) {
203
- moduleRegistered = true;
204
- resolvedModulePath = moduleUpdate.modulePath;
205
- }
206
- return {
207
- generatedFiles: writtenPaths,
208
- moduleRegistered: moduleRegistered,
209
- modulePath: resolvedModulePath,
210
- nextStepHint: generator.nextStepHint,
211
- plannedFiles: modulePlan ? [...plannedFiles, modulePlan] : plannedFiles,
212
- wiringBehavior: generator.wiringBehavior
213
- };
214
- }
1
+ export { runGenerateCommand } from '../generate-command.js';
@@ -32,12 +32,6 @@ export interface InspectCommandRuntimeOptions {
32
32
  /** Custom stream for standard output. */
33
33
  stdout?: CliStream;
34
34
  }
35
- /**
36
- * Returns the usage information string for the inspect command.
37
- *
38
- * @returns Formatted help text including usage and options.
39
- */
40
- export declare function inspectUsage(): string;
41
35
  /**
42
36
  * Executes the inspect command to visualize the application module graph.
43
37
  *
@@ -1 +1 @@
1
- {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AAMA,OAAO,EAOL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AAMzB,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,qBAAqB,GAAG,CAAC,QAAQ,EAAE,qBAAqB,KAAK,MAAM,CAAC;AAEzE,KAAK,2BAA2B,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;AAE/F;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,yEAAyE;IACzE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;IACxD,wFAAwF;IACxF,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,sCAAsC;IACtC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,yCAAyC;IACzC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAmFD;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAarC;AA+PD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,4BAAiC,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDnH"}
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AAMA,OAAO,EAOL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAC;AAMzB,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnE,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,qBAAqB,GAAG,CAAC,QAAQ,EAAE,qBAAqB,KAAK,MAAM,CAAC;AAEzE,KAAK,2BAA2B,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;AAE/F;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,yEAAyE;IACzE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;IACxD,wFAAwF;IACxF,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,sCAAsC;IACtC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,yCAAyC;IACzC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAoSD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,4BAAiC,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDnH"}
@@ -5,66 +5,19 @@ import { pathToFileURL } from 'node:url';
5
5
  import * as clack from '@clack/prompts';
6
6
  import { FluoFactory, PLATFORM_SHELL } from '@fluojs/runtime';
7
7
  import { tsImport } from 'tsx/esm/api';
8
- import { renderAliasList, renderHelpTable } from '../help.js';
9
8
  import { CliPromptCancelledError, isCliPromptCancelledError } from '../prompt-cancel.js';
9
+ import { inspectUsage } from '../usage.js';
10
10
 
11
11
  /**
12
12
  * Runtime options for the inspect command when used programmatically.
13
13
  */
14
14
 
15
- const INSPECT_OPTION_HELP = [{
16
- aliases: [],
17
- description: 'Emit the runtime platform snapshot/diagnostics payload as JSON (default when no output mode is selected).',
18
- option: '--json'
19
- }, {
20
- aliases: [],
21
- description: 'Emit a Mermaid graph through the optional @fluojs/studio rendering contract.',
22
- option: '--mermaid'
23
- }, {
24
- aliases: [],
25
- description: 'Include bootstrap timing diagnostics next to JSON inspect output.',
26
- option: '--timing'
27
- }, {
28
- aliases: [],
29
- description: 'Emit a CI-friendly JSON report with summary, snapshot, diagnostics, and timing.',
30
- option: '--report'
31
- }, {
32
- aliases: [],
33
- description: 'Write the selected inspect payload to a file instead of stdout.',
34
- option: '--output <path>'
35
- }, {
36
- aliases: [],
37
- description: 'Select the exported module symbol name (default: AppModule).',
38
- option: '--export <name>'
39
- }, {
40
- aliases: ['-h'],
41
- description: 'Show help for the inspect command.',
42
- option: '--help'
43
- }];
44
15
  const STUDIO_CONTRACT_ENTRYPOINT = '@fluojs/studio/contracts';
45
16
  const TYPESCRIPT_MODULE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);
46
17
  const STUDIO_MISSING_MESSAGE = ['Mermaid graph rendering is owned by @fluojs/studio, but @fluojs/studio is not resolvable from this project.', 'Install @fluojs/studio explicitly (for example: pnpm add -D @fluojs/studio) and rerun fluo inspect --mermaid.'].join('\n');
47
18
  function isHelpFlag(value) {
48
19
  return value === '--help' || value === '-h';
49
20
  }
50
-
51
- /**
52
- * Returns the usage information string for the inspect command.
53
- *
54
- * @returns Formatted help text including usage and options.
55
- */
56
- export function inspectUsage() {
57
- return ['Usage: fluo inspect <module-path> [options]', '', 'Options', renderHelpTable(INSPECT_OPTION_HELP, [{
58
- header: 'Option',
59
- render: entry => entry.option
60
- }, {
61
- header: 'Aliases',
62
- render: entry => renderAliasList(entry.aliases)
63
- }, {
64
- header: 'Description',
65
- render: entry => entry.description
66
- }]), '', 'Docs: https://github.com/fluojs/fluo/tree/main/docs/getting-started/quick-start.md'].join('\n');
67
- }
68
21
  function parseInspectArgs(argv) {
69
22
  let modulePath;
70
23
  let exportName = 'AppModule';
@@ -17,12 +17,6 @@ export interface NewCommandRuntimeOptions extends NewCommandOptions {
17
17
  stdout?: CliStream;
18
18
  userAgent?: string;
19
19
  }
20
- /**
21
- * Renders CLI help text for `fluo new`.
22
- *
23
- * @returns Stable help output for the scaffolding command.
24
- */
25
- export declare function newUsage(): string;
26
20
  /**
27
21
  * Executes `fluo new` with parsed arguments and scaffold options.
28
22
  *
@@ -1 +1 @@
1
- {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAOA,OAAO,EAA2B,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAWnF,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE3E,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAuBF;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0UD;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CA0BjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CA4G3G"}
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,iBAAiB,EAA2B,MAAM,kBAAkB,CAAC;AAWnF,OAAO,KAAK,EAAsC,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAI7F,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAiCF;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiPD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CA6G3G"}