@eudiplo/cli 7.1.1 → 7.2.0-main.20c3901

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 (268) hide show
  1. package/README.md +259 -15
  2. package/dist/commands/commands/index.d.ts +4 -0
  3. package/dist/commands/commands/index.d.ts.map +1 -0
  4. package/dist/commands/commands/index.js +13 -0
  5. package/dist/commands/commands/index.js.map +1 -0
  6. package/dist/commands/commands/render.d.ts +4 -0
  7. package/dist/commands/commands/render.d.ts.map +1 -0
  8. package/dist/commands/commands/render.js +52 -0
  9. package/dist/commands/commands/render.js.map +1 -0
  10. package/dist/commands/completion/action.d.ts +6 -0
  11. package/dist/commands/completion/action.d.ts.map +1 -0
  12. package/dist/commands/completion/action.js +133 -0
  13. package/dist/commands/completion/action.js.map +1 -0
  14. package/dist/commands/completion/index.d.ts +6 -0
  15. package/dist/commands/completion/index.d.ts.map +1 -0
  16. package/dist/commands/completion/index.js +23 -0
  17. package/dist/commands/completion/index.js.map +1 -0
  18. package/dist/commands/config/action.d.ts +4 -0
  19. package/dist/commands/config/action.d.ts.map +1 -0
  20. package/dist/commands/config/action.js +33 -0
  21. package/dist/commands/config/action.js.map +1 -0
  22. package/dist/commands/config/editor/action.d.ts +3 -0
  23. package/dist/commands/config/editor/action.d.ts.map +1 -0
  24. package/dist/commands/config/editor/action.js +112 -0
  25. package/dist/commands/config/editor/action.js.map +1 -0
  26. package/dist/commands/config/editor/index.d.ts +5 -0
  27. package/dist/commands/config/editor/index.d.ts.map +1 -0
  28. package/dist/commands/config/editor/index.js +20 -0
  29. package/dist/commands/config/editor/index.js.map +1 -0
  30. package/dist/commands/config/index.d.ts +5 -0
  31. package/dist/commands/config/index.d.ts.map +1 -0
  32. package/dist/commands/config/index.js +37 -0
  33. package/dist/commands/config/index.js.map +1 -0
  34. package/dist/commands/config/portability/action.d.ts +5 -0
  35. package/dist/commands/config/portability/action.d.ts.map +1 -0
  36. package/dist/commands/config/portability/action.js +164 -0
  37. package/dist/commands/config/portability/action.js.map +1 -0
  38. package/dist/commands/config/portability/index.d.ts +5 -0
  39. package/dist/commands/config/portability/index.d.ts.map +1 -0
  40. package/dist/commands/config/portability/index.js +44 -0
  41. package/dist/commands/config/portability/index.js.map +1 -0
  42. package/dist/commands/config/portability/migrations.d.ts +24 -0
  43. package/dist/commands/config/portability/migrations.d.ts.map +1 -0
  44. package/dist/commands/config/portability/migrations.js +95 -0
  45. package/dist/commands/config/portability/migrations.js.map +1 -0
  46. package/dist/commands/config/portability/migrations.spec.d.ts +2 -0
  47. package/dist/commands/config/portability/migrations.spec.d.ts.map +1 -0
  48. package/dist/commands/config/portability/migrations.spec.js +32 -0
  49. package/dist/commands/config/portability/migrations.spec.js.map +1 -0
  50. package/dist/commands/config/tenant/action.d.ts +3 -0
  51. package/dist/commands/config/tenant/action.d.ts.map +1 -0
  52. package/dist/commands/config/tenant/action.js +301 -0
  53. package/dist/commands/config/tenant/action.js.map +1 -0
  54. package/dist/commands/config/tenant/index.d.ts +5 -0
  55. package/dist/commands/config/tenant/index.d.ts.map +1 -0
  56. package/dist/commands/config/tenant/index.js +61 -0
  57. package/dist/commands/config/tenant/index.js.map +1 -0
  58. package/dist/commands/config/validate/action.d.ts +4 -0
  59. package/dist/commands/config/validate/action.d.ts.map +1 -0
  60. package/dist/commands/config/validate/action.js +47 -0
  61. package/dist/commands/config/validate/action.js.map +1 -0
  62. package/dist/commands/config/validate/index.d.ts +5 -0
  63. package/dist/commands/config/validate/index.d.ts.map +1 -0
  64. package/dist/commands/config/validate/index.js +18 -0
  65. package/dist/commands/config/validate/index.js.map +1 -0
  66. package/dist/commands/config/validate/registry.d.ts +6 -0
  67. package/dist/commands/config/validate/registry.d.ts.map +1 -0
  68. package/dist/{config-validate → commands/config/validate}/registry.js +2 -2
  69. package/dist/commands/config/validate/registry.js.map +1 -0
  70. package/dist/{config-validate → commands/config/validate}/registry.json +11 -22
  71. package/dist/commands/config/validate/report.d.ts.map +1 -0
  72. package/dist/{config-validate → commands/config/validate}/report.js +6 -1
  73. package/dist/commands/config/validate/report.js.map +1 -0
  74. package/dist/commands/config/validate/schemas.d.ts +3 -0
  75. package/dist/commands/config/validate/schemas.d.ts.map +1 -0
  76. package/dist/commands/config/validate/schemas.js +35 -0
  77. package/dist/commands/config/validate/schemas.js.map +1 -0
  78. package/dist/{config-validate → commands/config/validate}/types.d.ts +1 -1
  79. package/dist/commands/config/validate/types.d.ts.map +1 -0
  80. package/dist/commands/config/validate/types.js.map +1 -0
  81. package/dist/commands/config/validate/validator.d.ts.map +1 -0
  82. package/dist/{config-validate → commands/config/validate}/validator.js +17 -9
  83. package/dist/commands/config/validate/validator.js.map +1 -0
  84. package/dist/commands/demo/action.d.ts +3 -0
  85. package/dist/commands/demo/action.d.ts.map +1 -0
  86. package/dist/commands/demo/action.js +73 -0
  87. package/dist/commands/demo/action.js.map +1 -0
  88. package/dist/commands/demo/index.d.ts +5 -0
  89. package/dist/commands/demo/index.d.ts.map +1 -0
  90. package/dist/commands/demo/index.js +19 -0
  91. package/dist/commands/demo/index.js.map +1 -0
  92. package/dist/commands/deployment/action.d.ts +3 -0
  93. package/dist/commands/deployment/action.d.ts.map +1 -0
  94. package/dist/commands/deployment/action.js +23 -0
  95. package/dist/commands/deployment/action.js.map +1 -0
  96. package/dist/commands/deployment/index.d.ts +5 -0
  97. package/dist/commands/deployment/index.d.ts.map +1 -0
  98. package/dist/commands/deployment/index.js +19 -0
  99. package/dist/commands/deployment/index.js.map +1 -0
  100. package/dist/commands/doctor/action.d.ts +3 -0
  101. package/dist/commands/doctor/action.d.ts.map +1 -0
  102. package/dist/commands/doctor/action.js +12 -0
  103. package/dist/commands/doctor/action.js.map +1 -0
  104. package/dist/commands/doctor/index.d.ts +5 -0
  105. package/dist/commands/doctor/index.d.ts.map +1 -0
  106. package/dist/commands/doctor/index.js +13 -0
  107. package/dist/commands/doctor/index.js.map +1 -0
  108. package/dist/commands/init/action.d.ts +3 -0
  109. package/dist/commands/init/action.d.ts.map +1 -0
  110. package/dist/commands/init/action.js +255 -0
  111. package/dist/commands/init/action.js.map +1 -0
  112. package/dist/commands/init/index.d.ts +5 -0
  113. package/dist/commands/init/index.d.ts.map +1 -0
  114. package/dist/commands/init/index.js +35 -0
  115. package/dist/commands/init/index.js.map +1 -0
  116. package/dist/commands/instance/action.d.ts +7 -0
  117. package/dist/commands/instance/action.d.ts.map +1 -0
  118. package/dist/commands/instance/action.js +85 -0
  119. package/dist/commands/instance/action.js.map +1 -0
  120. package/dist/commands/instance/index.d.ts +5 -0
  121. package/dist/commands/instance/index.d.ts.map +1 -0
  122. package/dist/commands/instance/index.js +53 -0
  123. package/dist/commands/instance/index.js.map +1 -0
  124. package/dist/commands/shared.d.ts +14 -0
  125. package/dist/commands/shared.d.ts.map +1 -0
  126. package/dist/commands/shared.js +39 -0
  127. package/dist/commands/shared.js.map +1 -0
  128. package/dist/commands/status/action.d.ts +3 -0
  129. package/dist/commands/status/action.d.ts.map +1 -0
  130. package/dist/commands/status/action.js +13 -0
  131. package/dist/commands/status/action.js.map +1 -0
  132. package/dist/commands/status/index.d.ts +5 -0
  133. package/dist/commands/status/index.d.ts.map +1 -0
  134. package/dist/commands/status/index.js +13 -0
  135. package/dist/commands/status/index.js.map +1 -0
  136. package/dist/commands/version/action.d.ts +4 -0
  137. package/dist/commands/version/action.d.ts.map +1 -0
  138. package/dist/commands/version/action.js +70 -0
  139. package/dist/commands/version/action.js.map +1 -0
  140. package/dist/commands/version/index.d.ts +6 -0
  141. package/dist/commands/version/index.d.ts.map +1 -0
  142. package/dist/commands/version/index.js +12 -0
  143. package/dist/commands/version/index.js.map +1 -0
  144. package/dist/index.js +0 -0
  145. package/dist/options.d.ts +2 -0
  146. package/dist/options.d.ts.map +1 -0
  147. package/dist/options.js +5 -0
  148. package/dist/options.js.map +1 -0
  149. package/dist/runtime.d.ts +2 -0
  150. package/dist/runtime.d.ts.map +1 -1
  151. package/dist/runtime.js +61 -465
  152. package/dist/runtime.js.map +1 -1
  153. package/dist/sea-assets.d.ts +4 -2
  154. package/dist/sea-assets.d.ts.map +1 -1
  155. package/dist/sea-assets.js +6 -3
  156. package/dist/sea-assets.js.map +1 -1
  157. package/dist/{config.d.ts → services/cli-config.d.ts} +4 -2
  158. package/dist/services/cli-config.d.ts.map +1 -0
  159. package/dist/{config.js → services/cli-config.js} +30 -4
  160. package/dist/services/cli-config.js.map +1 -0
  161. package/dist/{compose-template.d.ts → services/compose-project.d.ts} +14 -4
  162. package/dist/services/compose-project.d.ts.map +1 -0
  163. package/dist/services/compose-project.js +189 -0
  164. package/dist/services/compose-project.js.map +1 -0
  165. package/dist/{drivers.d.ts → services/deployment-drivers.d.ts} +16 -3
  166. package/dist/services/deployment-drivers.d.ts.map +1 -0
  167. package/dist/services/deployment-drivers.js +288 -0
  168. package/dist/services/deployment-drivers.js.map +1 -0
  169. package/dist/services/deployment-target.d.ts +3 -0
  170. package/dist/services/deployment-target.d.ts.map +1 -0
  171. package/dist/services/deployment-target.js +7 -0
  172. package/dist/services/deployment-target.js.map +1 -0
  173. package/dist/{doctor.d.ts → services/diagnostics.d.ts} +2 -2
  174. package/dist/services/diagnostics.d.ts.map +1 -0
  175. package/dist/{doctor.js → services/diagnostics.js} +4 -2
  176. package/dist/services/diagnostics.js.map +1 -0
  177. package/dist/services/instance-selection.d.ts +3 -0
  178. package/dist/services/instance-selection.d.ts.map +1 -0
  179. package/dist/services/instance-selection.js +13 -0
  180. package/dist/services/instance-selection.js.map +1 -0
  181. package/dist/services/project-directory.d.ts +3 -0
  182. package/dist/services/project-directory.d.ts.map +1 -0
  183. package/dist/services/project-directory.js +14 -0
  184. package/dist/services/project-directory.js.map +1 -0
  185. package/dist/types.d.ts +4 -0
  186. package/dist/types.d.ts.map +1 -1
  187. package/package.json +7 -4
  188. package/templates/demo-config/issuance/issuance.json +20 -12
  189. package/templates/demo-config/key-chains/access.json +13 -2
  190. package/templates/demo-config/key-chains/attestation.json +15 -4
  191. package/templates/demo-config/key-chains/status-list.json +15 -4
  192. package/templates/demo-config/key-chains/trust-list.json +13 -2
  193. package/templates/demo-config/presentation/age-over-18.json +46 -53
  194. package/templates/demo-config/presentation/pid.json +44 -0
  195. package/templates/demo-config.manifest.json +1 -0
  196. package/templates/docker-compose.yml +5 -4
  197. package/templates/schemas/AttributeProviderAuth.schema.json +60 -0
  198. package/templates/schemas/AttributeProviderConfigFile.schema.json +37 -0
  199. package/templates/schemas/CertImportDto.schema.json +35 -0
  200. package/templates/schemas/ClientConfigFile.schema.json +37 -0
  201. package/templates/schemas/ConfigDocumentMetadata.schema.json +25 -0
  202. package/templates/schemas/CreateClientDto.schema.json +1 -0
  203. package/templates/schemas/CreateStatusListDto.schema.json +46 -0
  204. package/templates/schemas/CreateTenantDto.schema.json +116 -0
  205. package/templates/schemas/CredentialConfigCreate.schema.json +55 -0
  206. package/templates/schemas/CredentialConfigFile.schema.json +37 -0
  207. package/templates/schemas/DCQL.schema.json +401 -0
  208. package/templates/schemas/EmbeddedDisclosurePolicy.schema.json +106 -0
  209. package/templates/schemas/ImportTenantDto.schema.json +69 -0
  210. package/templates/schemas/IssuanceConfig.schema.json +26 -6
  211. package/templates/schemas/IssuanceConfigFile.schema.json +32 -0
  212. package/templates/schemas/KeyChainConfigFile.schema.json +101 -0
  213. package/templates/schemas/KeyChainCreateDto.schema.json +66 -0
  214. package/templates/schemas/KeyChainUpdateDto.schema.json +40 -0
  215. package/templates/schemas/KmsConfigFile.schema.json +37 -0
  216. package/templates/schemas/PresentationConfigFile.schema.json +32 -0
  217. package/templates/schemas/RegistrarConfigFile.schema.json +37 -0
  218. package/templates/schemas/RotationPolicyCreateDto.schema.json +28 -0
  219. package/templates/schemas/RotationPolicyUpdateDto.schema.json +25 -0
  220. package/templates/schemas/SessionStorageConfig.schema.json +24 -0
  221. package/templates/schemas/StatusListConfig.schema.json +51 -0
  222. package/templates/schemas/StatusListConfigFile.schema.json +37 -0
  223. package/templates/schemas/TransactionData.schema.json +24 -0
  224. package/templates/schemas/TrustListConfigFile.schema.json +37 -0
  225. package/templates/schemas/UpdateAttributeProviderDto.schema.json +93 -0
  226. package/templates/schemas/UpdateClientDto.schema.json +62 -0
  227. package/templates/schemas/UpdateStatusListConfigDto.schema.json +85 -0
  228. package/templates/schemas/UpdateStatusListDto.schema.json +33 -0
  229. package/templates/schemas/UpdateTenantDto.schema.json +96 -0
  230. package/templates/schemas/UpdateWebhookEndpointDto.schema.json +93 -0
  231. package/templates/schemas/VCT.schema.json +37 -0
  232. package/templates/schemas/WebhookConfig.schema.json +80 -0
  233. package/templates/schemas/WebhookEndpointConfigFile.schema.json +37 -0
  234. package/templates/schemas.manifest.json +34 -1
  235. package/dist/args.d.ts +0 -4
  236. package/dist/args.d.ts.map +0 -1
  237. package/dist/args.js +0 -46
  238. package/dist/args.js.map +0 -1
  239. package/dist/compose-template.d.ts.map +0 -1
  240. package/dist/compose-template.js +0 -105
  241. package/dist/compose-template.js.map +0 -1
  242. package/dist/config-validate/index.d.ts +0 -4
  243. package/dist/config-validate/index.d.ts.map +0 -1
  244. package/dist/config-validate/index.js +0 -4
  245. package/dist/config-validate/index.js.map +0 -1
  246. package/dist/config-validate/registry.d.ts +0 -5
  247. package/dist/config-validate/registry.d.ts.map +0 -1
  248. package/dist/config-validate/registry.js.map +0 -1
  249. package/dist/config-validate/report.d.ts.map +0 -1
  250. package/dist/config-validate/report.js.map +0 -1
  251. package/dist/config-validate/schemas.d.ts +0 -2
  252. package/dist/config-validate/schemas.d.ts.map +0 -1
  253. package/dist/config-validate/schemas.js +0 -24
  254. package/dist/config-validate/schemas.js.map +0 -1
  255. package/dist/config-validate/types.d.ts.map +0 -1
  256. package/dist/config-validate/types.js.map +0 -1
  257. package/dist/config-validate/validator.d.ts.map +0 -1
  258. package/dist/config-validate/validator.js.map +0 -1
  259. package/dist/config.d.ts.map +0 -1
  260. package/dist/config.js.map +0 -1
  261. package/dist/doctor.d.ts.map +0 -1
  262. package/dist/doctor.js.map +0 -1
  263. package/dist/drivers.d.ts.map +0 -1
  264. package/dist/drivers.js +0 -170
  265. package/dist/drivers.js.map +0 -1
  266. /package/dist/{config-validate → commands/config/validate}/report.d.ts +0 -0
  267. /package/dist/{config-validate → commands/config/validate}/types.js +0 -0
  268. /package/dist/{config-validate → commands/config/validate}/validator.d.ts +0 -0
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # EUDIPLO CLI
2
2
 
3
3
  The EUDIPLO CLI provides deployment-neutral commands for inspecting an EUDIPLO
4
- instance and deployment-driver commands for local Docker Compose demos.
4
+ instance and deployment-driver commands for local Compose demos.
5
5
 
6
6
  For installation, command reference, configuration validation, standalone
7
7
  releases, and local development, see the [CLI documentation](../../docs/getting-started/cli.md).
@@ -9,34 +9,39 @@ releases, and local development, see the [CLI documentation](../../docs/getting-
9
9
  ## Quick Start
10
10
 
11
11
  This package is the npm distribution of the **EUDIPLO CLI** and requires
12
- Node.js 22+.
12
+ Node.js 22.12+.
13
13
 
14
14
  For users who do not want a local Node.js dependency, use the standalone CLI
15
15
  installer instead: `curl -fsSL https://eudiplo.dev/install.sh | bash`
16
16
 
17
17
  ```bash
18
- npx @eudiplo/cli demo
18
+ npx @eudiplo/cli demo ./eudiplo-demo
19
19
  npx @eudiplo/cli instance add production --url https://eudiplo.example.com
20
+ npx @eudiplo/cli instance ls
21
+ npx @eudiplo/cli instance show production
22
+ npx @eudiplo/cli instance use production
20
23
  npx @eudiplo/cli doctor --instance production
21
24
  ```
22
25
 
23
26
  `demo` creates a local editable demo deployment, writes `.eudiplo.demo.env`,
24
- copies canonical demo configuration into `.eudiplo/demo-config`, and starts the
25
- `compose` driver.
27
+ copies canonical demo configuration into `config/demo`, and starts the
28
+ minimal `compose` stack. It always uses SQLite, local file storage,
29
+ database-backed key management, the backend, and the web client.
26
30
 
27
31
  - Backend image: `ghcr.io/openwallet-foundation/eudiplo:<tag>`
28
32
  - Client image: `ghcr.io/openwallet-foundation/eudiplo-client:<tag>`
29
33
 
30
- Tag selection defaults to the CLI version. For prerelease versions containing
31
- `-main.`, the CLI uses the `main` tag for both images. Use `--image-tag` (or
32
- `EUDIPLO_IMAGE_TAG`) to override.
34
+ Tag selection defaults to `latest` for both images. Use `--image-tag` (or
35
+ `EUDIPLO_IMAGE_TAG`) to select `main`, a release tag, or an immutable SHA tag.
33
36
 
34
37
  The generated demo config remains editable after creation. Existing files are
35
38
  preserved unless you pass `--force`.
36
39
 
37
40
  The standalone CLI and this npm package are two distributions of the same
38
41
  `eudiplo` command. The standalone CLI removes the Node.js requirement, but
39
- Docker and Docker Compose are still required for the demo deployment.
42
+ Docker and Docker Compose, or Podman and Podman Compose, are still required for
43
+ the demo deployment. Docker is preferred by default; set
44
+ `EUDIPLO_CONTAINER_RUNTIME=podman` to force Podman.
40
45
 
41
46
  ## Package and Binary Names
42
47
 
@@ -52,12 +57,34 @@ pnpm add -D @eudiplo/cli
52
57
  pnpm eudiplo status
53
58
  ```
54
59
 
60
+ ## Uninstall
61
+
62
+ Use the removal path that matches how the CLI was installed:
63
+
64
+ ```bash
65
+ # Standalone Linux/macOS installer
66
+ rm "${EUDIPLO_INSTALL_DIR:-$HOME/.local/bin}/eudiplo"
67
+
68
+ # npm global install
69
+ npm uninstall -g @eudiplo/cli
70
+
71
+ # project dependency
72
+ pnpm remove @eudiplo/cli
73
+ ```
74
+
75
+ The CLI stores instance metadata in `~/.eudiplo/config.json` by default. Remove
76
+ `~/.eudiplo` only if you also want to delete local CLI instance registrations.
77
+
55
78
  ## Compose Driver Commands
56
79
 
57
80
  Compose driver commands require a `compose` instance:
58
81
 
59
82
  ```bash
60
- eudiplo init --target compose
83
+ eudiplo init
84
+ eudiplo init ./eudiplo-minimal --preset minimal
85
+ eudiplo init ./eudiplo-standard --preset standard --start
86
+ eudiplo init --database postgres --storage local --kms vault
87
+ eudiplo init --preset standard --demo-tenant
61
88
  eudiplo init --target compose --demo
62
89
  eudiplo init --target compose --demo --image-tag main
63
90
  eudiplo init --target compose --no-client
@@ -67,14 +94,49 @@ eudiplo logs
67
94
  eudiplo demo --reset --force
68
95
  ```
69
96
 
70
- `init --target compose` writes a local `.eudiplo.env` using Compose defaults.
97
+ In an interactive terminal, `init` opens a wizard for the project directory,
98
+ preset, components, public URL, authentication, client, and startup choices.
99
+ For scripts and CI, the same values can be supplied with `--directory`,
100
+ `--preset`, `--database`, `--storage`, `--kms`, `--public-url`,
101
+ `--auth-client-id`, and `--auth-client-secret`. The directory can also be passed
102
+ positionally. When it is omitted, the wizard suggests `./`; non-interactive and
103
+ `--yes` runs use `./` automatically. Its absolute path is saved with the
104
+ instance, allowing later Compose commands to run from a different working
105
+ directory.
106
+
107
+ Interactive `demo` runs use the same directory prompt. Pass a positional
108
+ directory, `--directory`, or `--yes` to skip it.
109
+
110
+ `init --preset minimal` writes a local `.eudiplo.env` using SQLite and local
111
+ storage. `standard` provisions PostgreSQL and MinIO, while `full` additionally
112
+ provisions Vault. Arbitrary combinations are supported through the component
113
+ flags.
114
+
115
+ Every initialized project contains one mounted `config/` root. Global KMS
116
+ configuration is written to `config/kms.json`, while tenant configuration is
117
+ stored under `config/<tenant-id>/`. The demo tenant is excluded by default and
118
+ can be added with `--demo-tenant`.
119
+
71
120
  `init --target compose --demo` writes demo-specific assets (`.eudiplo.demo.env`
72
- and `.eudiplo/demo-config`) without starting Docker Compose. Add `--no-client`
121
+ and `config/demo`) without starting the Compose runtime. Add `--no-client`
73
122
  to generate a small Compose override that skips the web client container.
74
123
 
75
124
  `demo --reset --force` stops the managed demo stack, removes managed demo
76
125
  volumes, and recreates only CLI-managed demo assets.
77
126
 
127
+ ## Local Tenant Configuration Commands
128
+
129
+ ```bash
130
+ eudiplo config tenant list
131
+ eudiplo config tenant create acme --name "Acme GmbH"
132
+ eudiplo config tenant create sample --template demo
133
+ eudiplo config tenant remove acme --force
134
+ ```
135
+
136
+ The aliases `ls`, `new`, `rm`, and `delete` are also supported. These commands manage
137
+ local config-import folders only; removing a folder does not delete an already
138
+ imported tenant from a running EUDIPLO instance.
139
+
78
140
  If a driver-specific command is used with an unsupported target, the CLI exits
79
141
  with a clear error, for example:
80
142
 
@@ -92,10 +154,30 @@ EUDIPLO_CLI_HOME=/tmp/eudiplo-cli eudiplo config validate
92
154
  EUDIPLO_CLI_CONFIG=/tmp/eudiplo-cli/config.json eudiplo config validate
93
155
  ```
94
156
 
157
+ Print the resolved file path or inspect the validated configuration with:
158
+
159
+ ```bash
160
+ eudiplo config path
161
+ eudiplo config show
162
+ eudiplo config show --json
163
+ ```
164
+
95
165
  Do not store secrets in the CLI config. Commands that need authenticated API
96
166
  access read credentials from environment variables such as `EUDIPLO_CLIENT_ID`
97
167
  and `EUDIPLO_CLIENT_SECRET`.
98
168
 
169
+ ## Shell Completion
170
+
171
+ The CLI generates completion scripts for Bash, Zsh, Fish, and PowerShell. For
172
+ the current shell session, use one of:
173
+
174
+ ```bash
175
+ source <(eudiplo completion bash)
176
+ source <(eudiplo completion zsh)
177
+ eudiplo completion fish | source
178
+ eudiplo completion powershell | Out-String | Invoke-Expression
179
+ ```
180
+
99
181
  ## Single Executable Application
100
182
 
101
183
  To produce a standalone CLI binary with Node.js SEA support, run:
@@ -142,6 +224,168 @@ running it:
142
224
  sha256sum -c SHA256SUMS.txt
143
225
  ```
144
226
 
145
- The standalone binary does not replace Docker or Docker Compose. You still need
146
- Docker to run the local deployment stack, but you do not need a local Node.js
147
- installation just to use the CLI itself.
227
+ The standalone binary does not replace Docker, Podman, or Compose. You still
228
+ need a container runtime to run the local deployment stack, but you do not need a
229
+ local Node.js installation just to use the CLI itself.
230
+
231
+ ## Developing and Extending the CLI
232
+
233
+ The CLI uses Commander and an injectable `CommandContext`. Command definitions
234
+ are organized under `src/commands`; `src/runtime.ts` only assembles the command
235
+ tree and connects Commander output and exit handling to the current context.
236
+
237
+ ### Running the CLI locally
238
+
239
+ Append CLI arguments directly after the `dev` script. `init` is a root command,
240
+ while `config` contains only configuration-related subcommands:
241
+
242
+ ```bash
243
+ pnpm --filter @eudiplo/cli dev init ./eudiplo-local --yes
244
+ pnpm --filter @eudiplo/cli dev config tenant list
245
+ ```
246
+
247
+ Generated Compose projects use `latest` by default and do not derive container
248
+ tags from `apps/cli/package.json`. Select `main` or an immutable SHA explicitly
249
+ when testing changes that require a different backend or client build:
250
+
251
+ ```bash
252
+ pnpm --filter @eudiplo/cli dev demo ./eudiplo-demo --image-tag main
253
+ ```
254
+
255
+ Install the JSON Schemas bundled with the CLI into a VS Code workspace and
256
+ associate them with the local tenant configuration tree:
257
+
258
+ ```bash
259
+ eudiplo config editor setup . --config-directory ./config
260
+ ```
261
+
262
+ The command merges `.vscode/settings.json` without removing unrelated settings
263
+ or JSONC comments and can safely be rerun after a CLI upgrade.
264
+
265
+ List the complete command tree or render the same reference as Markdown:
266
+
267
+ ```bash
268
+ eudiplo commands
269
+ eudiplo commands --format markdown
270
+ ```
271
+
272
+ The documentation prebuild uses the Markdown renderer directly, keeping the
273
+ published command reference synchronized with Commander definitions.
274
+
275
+ Use a new project directory or add `--force` when regenerating an existing
276
+ project, because the CLI preserves managed environment files by default. The
277
+ `version` command still reports the CLI package version, but that value is not
278
+ used for container image selection.
279
+
280
+ ```text
281
+ src/
282
+ ├── runtime.ts # creates the root Commander program
283
+ ├── commands/
284
+ │ ├── demo/
285
+ │ │ ├── index.ts # command registration and options
286
+ │ │ └── action.ts # demo workflow
287
+ │ ├── init/
288
+ │ │ ├── index.ts # command registration and wizard options
289
+ │ │ └── action.ts # initialization workflow
290
+ │ ├── instance/
291
+ │ │ ├── index.ts # command group and its subcommands
292
+ │ │ └── action.ts # instance persistence
293
+ │ └── config/
294
+ │ ├── index.ts # config group
295
+ │ ├── editor/ # VS Code schema setup command module
296
+ │ ├── validate/ # validation command module
297
+ │ └── tenant/ # tenant-config command module
298
+ ├── services/
299
+ │ ├── cli-config.ts # persisted CLI instance configuration
300
+ │ ├── compose-project.ts # generated Compose assets
301
+ │ ├── deployment-drivers.ts # Compose and external drivers
302
+ │ └── diagnostics.ts # deployment health checks
303
+ └── types.ts # injectable context and shared CLI types
304
+ ```
305
+
306
+ ### Adding a root command
307
+
308
+ Create a directory for the command with `index.ts` as its public entrypoint and
309
+ `action.ts` for its workflow. Declare arguments, options, validation,
310
+ descriptions, and aliases in `index.ts` so generated help remains the source of
311
+ truth.
312
+
313
+ ```ts
314
+ // commands/example/index.ts
315
+ import { Command } from 'commander';
316
+ import type { CommandContext } from '../../types.js';
317
+ import type { SetExitCode } from '../shared.js';
318
+ import { runExample } from './action.js';
319
+
320
+ export function createExampleCommand(
321
+ context: CommandContext,
322
+ setExitCode: SetExitCode,
323
+ ): Command {
324
+ return new Command('example')
325
+ .description('Describe what the command does')
326
+ .requiredOption('--input <path>', 'input file')
327
+ .action(async (options) => {
328
+ setExitCode(await runExample(options.input, context));
329
+ });
330
+ }
331
+ ```
332
+
333
+ ```ts
334
+ // commands/example/action.ts
335
+ import type { CommandContext } from '../../types.js';
336
+
337
+ export async function runExample(
338
+ input: string,
339
+ context: CommandContext,
340
+ ): Promise<number> {
341
+ context.stdout.write(`Processing ${input}\n`);
342
+ return 0;
343
+ }
344
+ ```
345
+
346
+ Register the factory once in `createProgram` in `src/runtime.ts`. Do not add a
347
+ root dispatch switch or manually maintained help text.
348
+
349
+ ### Adding nested commands
350
+
351
+ Create a parent `Command`, add independently configured child modules with
352
+ `addCommand`, and return the parent from its factory. Each nested command gets
353
+ the same `index.ts` plus `action.ts` structure. `config/tenant` and
354
+ `config/validate` are the reference patterns.
355
+
356
+ Keep these boundaries when extending the command tree:
357
+
358
+ - A command module owns its registration, options, action, and command-specific
359
+ helpers.
360
+ - `services/` is only for infrastructure shared by multiple command modules,
361
+ such as config persistence, Compose generation, and instance selection.
362
+ - Load CLI state lazily inside actions that require it; help must work without a
363
+ valid local configuration.
364
+ - Write through `CommandContext.stdout` and `CommandContext.stderr`; do not call
365
+ `console.log` or `process.exit` from a command.
366
+ - Throw normal errors for operational failures. Let Commander handle unknown
367
+ options, required arguments, choices, aliases, and contextual help.
368
+ - Prefer a coherent command structure over preserving accidental parser
369
+ behavior. Document intentional breaking syntax changes in the user guides.
370
+
371
+ Runtime dependencies are welcome when they materially improve usability or
372
+ maintainability. They must support ESM, Node.js 22.12+, TypeScript, and the
373
+ single-executable bundle. Avoid dependencies that require spawning separate
374
+ subcommand executables, because the released CLI is also packaged as one SEA
375
+ binary.
376
+
377
+ ### Testing a command change
378
+
379
+ Exercise commands through `runCli(args, context)` so tests cover the real
380
+ Commander tree while keeping output, environment variables, prompts, and
381
+ network access injectable. Add coverage for successful execution, invalid
382
+ arguments or options, and the relevant help level.
383
+
384
+ Run the complete CLI verification before submitting a change:
385
+
386
+ ```bash
387
+ pnpm --filter @eudiplo/cli test
388
+ pnpm --filter @eudiplo/cli lint
389
+ pnpm --filter @eudiplo/cli build
390
+ pnpm --filter @eudiplo/cli build:sea:bundle
391
+ ```
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import type { CommandContext } from "../../types.js";
3
+ export declare function createCommandsCommand(context: CommandContext, getProgram: () => Command): Command;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMrD,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,MAAM,OAAO,GAC1B,OAAO,CAaT"}
@@ -0,0 +1,13 @@
1
+ import { Command, Option } from "commander";
2
+ import { renderCommandReference, } from "./render.js";
3
+ export function createCommandsCommand(context, getProgram) {
4
+ return new Command("commands")
5
+ .description("List every available CLI command")
6
+ .addOption(new Option("--format <text|markdown>", "output format")
7
+ .choices(["text", "markdown"])
8
+ .default("text"))
9
+ .action((options) => {
10
+ context.stdout.write(renderCommandReference(getProgram(), options.format));
11
+ });
12
+ }
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,EAEH,sBAAsB,GACzB,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,qBAAqB,CACjC,OAAuB,EACvB,UAAyB;IAEzB,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;SACzB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,SAAS,CACN,IAAI,MAAM,CAAC,0BAA0B,EAAE,eAAe,CAAC;SAClD,OAAO,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;SAC7B,OAAO,CAAC,MAAM,CAAC,CACvB;SACA,MAAM,CAAC,CAAC,OAA2C,EAAE,EAAE;QACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAChB,sBAAsB,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CACvD,CAAC;IACN,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ export type CommandReferenceFormat = "text" | "markdown";
3
+ export declare function renderCommandReference(program: Command, format: CommandReferenceFormat): string;
4
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/commands/commands/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEzD,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,sBAAsB,GAC/B,MAAM,CAIR"}
@@ -0,0 +1,52 @@
1
+ export function renderCommandReference(program, format) {
2
+ return format === "markdown"
3
+ ? renderMarkdownReference(program)
4
+ : renderTextReference(program);
5
+ }
6
+ function renderTextReference(program) {
7
+ const commands = collectCommands(program).slice(1);
8
+ const rows = commands.map((command) => ({
9
+ invocation: usageLine(command),
10
+ description: command.description(),
11
+ }));
12
+ const invocationWidth = Math.max(...rows.map((row) => row.invocation.length));
13
+ const lines = rows.map((row) => ` ${row.invocation.padEnd(invocationWidth)} ${row.description}`.trimEnd());
14
+ return `Available commands:\n\n${lines.join("\n")}\n`;
15
+ }
16
+ function renderMarkdownReference(program) {
17
+ const sections = collectCommands(program).map((command, index) => {
18
+ const heading = index === 0
19
+ ? "# EUDIPLO CLI command reference"
20
+ : `## \`${commandPath(command)}\``;
21
+ const description = index === 0
22
+ ? "Generated from the CLI command definitions. Do not edit this page manually."
23
+ : command.description();
24
+ return `${heading}\n\n${description}\n\n\`\`\`text\n${command.helpInformation().trim()}\n\`\`\``;
25
+ });
26
+ return `${sections.join("\n\n")}\n`;
27
+ }
28
+ function collectCommands(program) {
29
+ const commands = [program];
30
+ for (const child of program.commands) {
31
+ if (child.name() === "help" ||
32
+ child._hidden === true) {
33
+ continue;
34
+ }
35
+ commands.push(...collectCommands(child));
36
+ }
37
+ return commands;
38
+ }
39
+ function usageLine(command) {
40
+ const firstLine = command.helpInformation().split("\n", 1)[0];
41
+ return firstLine.replace(/^Usage:\s*/, "");
42
+ }
43
+ function commandPath(command) {
44
+ const names = [];
45
+ let current = command;
46
+ while (current) {
47
+ names.unshift(current.name());
48
+ current = current.parent;
49
+ }
50
+ return names.join(" ");
51
+ }
52
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/commands/commands/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Command } from "commander";
2
+ import type { CommandContext } from "../../types.js";
3
+ export type CompletionShell = "bash" | "zsh" | "fish" | "powershell";
4
+ export declare function runCompletion(shell: CompletionShell, context: CommandContext): number;
5
+ export declare function runCompletionCandidates(root: Command, words: string[], context: CommandContext): number;
6
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/completion/action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,YAAY,CAAC;AAErE,wBAAgB,aAAa,CACzB,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,cAAc,GACxB,MAAM,CAGR;AAED,wBAAgB,uBAAuB,CACnC,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,cAAc,GACxB,MAAM,CAKR"}
@@ -0,0 +1,133 @@
1
+ export function runCompletion(shell, context) {
2
+ context.stdout.write(`${completionScript(shell)}\n`);
3
+ return 0;
4
+ }
5
+ export function runCompletionCandidates(root, words, context) {
6
+ for (const candidate of completionCandidates(root, words)) {
7
+ context.stdout.write(`${candidate}\n`);
8
+ }
9
+ return 0;
10
+ }
11
+ function completionScript(shell) {
12
+ switch (shell) {
13
+ case "bash":
14
+ return bashCompletion();
15
+ case "zsh":
16
+ return zshCompletion();
17
+ case "fish":
18
+ return fishCompletion();
19
+ case "powershell":
20
+ return powershellCompletion();
21
+ }
22
+ }
23
+ function completionCandidates(root, words) {
24
+ let current = root;
25
+ let skipOptionValue = false;
26
+ for (const word of words) {
27
+ if (skipOptionValue) {
28
+ skipOptionValue = false;
29
+ continue;
30
+ }
31
+ const option = findOption(current, word);
32
+ if (option) {
33
+ skipOptionValue = option.required || option.optional;
34
+ continue;
35
+ }
36
+ if (word.startsWith("-")) {
37
+ continue;
38
+ }
39
+ const child = current.commands.find((command) => command.name() === word || command.aliases().includes(word));
40
+ if (child) {
41
+ current = child;
42
+ }
43
+ }
44
+ const lastOption = findOption(current, words.at(-1));
45
+ if (lastOption) {
46
+ const choices = optionChoices(lastOption);
47
+ if (choices.length > 0) {
48
+ return choices;
49
+ }
50
+ }
51
+ const candidates = ["-h", "--help"];
52
+ for (const command of current.commands) {
53
+ if (command.name() !== "_complete") {
54
+ candidates.push(command.name(), ...command.aliases());
55
+ }
56
+ }
57
+ for (const option of current.options) {
58
+ if (option.short) {
59
+ candidates.push(option.short);
60
+ }
61
+ if (option.long) {
62
+ candidates.push(option.long);
63
+ }
64
+ }
65
+ if (current.commands.length === 0 && words.at(-1) === current.name()) {
66
+ candidates.push(...(current.registeredArguments[0]?.argChoices ?? []));
67
+ }
68
+ return [...new Set(candidates)];
69
+ }
70
+ function findOption(command, word) {
71
+ if (!word) {
72
+ return undefined;
73
+ }
74
+ const flag = word.includes("=") ? word.slice(0, word.indexOf("=")) : word;
75
+ return command.options.find((option) => option.short === flag || option.long === flag);
76
+ }
77
+ function optionChoices(option) {
78
+ if (option.argChoices) {
79
+ return option.argChoices;
80
+ }
81
+ const placeholder = option.flags.match(/[<[]([^>\]]+)[>\]]/u)?.[1];
82
+ return placeholder?.includes("|") ? placeholder.split("|") : [];
83
+ }
84
+ function bashCompletion() {
85
+ return [
86
+ "_eudiplo_completion() {",
87
+ " local current candidates",
88
+ " local -a args",
89
+ ' current="${COMP_WORDS[COMP_CWORD]}"',
90
+ ' args=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")',
91
+ ' candidates="$(eudiplo _complete "${args[@]}" 2>/dev/null)"',
92
+ ' COMPREPLY=($(compgen -W "$candidates" -- "$current"))',
93
+ "}",
94
+ "complete -F _eudiplo_completion eudiplo",
95
+ ].join("\n");
96
+ }
97
+ function zshCompletion() {
98
+ return [
99
+ "#compdef eudiplo",
100
+ "_eudiplo() {",
101
+ " local -a args candidates",
102
+ ' args=("${words[@]:2:$((CURRENT - 2))}")',
103
+ ' candidates=("${(@f)$(eudiplo _complete "${args[@]}" 2>/dev/null)}")',
104
+ " compadd -- $candidates",
105
+ "}",
106
+ "compdef _eudiplo eudiplo",
107
+ ].join("\n");
108
+ }
109
+ function fishCompletion() {
110
+ return [
111
+ "function __eudiplo_candidates",
112
+ " set -l tokens (commandline -opc)",
113
+ " set -e tokens[1]",
114
+ " eudiplo _complete $tokens 2>/dev/null",
115
+ "end",
116
+ "complete -c eudiplo -f -a '(__eudiplo_candidates)'",
117
+ ].join("\n");
118
+ }
119
+ function powershellCompletion() {
120
+ return [
121
+ "Register-ArgumentCompleter -Native -CommandName eudiplo -ScriptBlock {",
122
+ " param($wordToComplete, $commandAst, $cursorPosition)",
123
+ " $arguments = @($commandAst.CommandElements | Select-Object -Skip 1 | ForEach-Object { $_.ToString() })",
124
+ " if ($wordToComplete -and $arguments.Count -gt 0) {",
125
+ " $arguments = @($arguments | Select-Object -First ($arguments.Count - 1))",
126
+ " }",
127
+ " eudiplo _complete @arguments 2>$null | Where-Object { $_ -like \"$wordToComplete*\" } | ForEach-Object {",
128
+ " [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)",
129
+ " }",
130
+ "}",
131
+ ].join("\n");
132
+ }
133
+ //# sourceMappingURL=action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.js","sourceRoot":"","sources":["../../../src/commands/completion/action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from "commander";
2
+ import type { CommandContext } from "../../types.js";
3
+ import type { SetExitCode } from "../shared.js";
4
+ export declare function createCompletionCommand(context: CommandContext, setExitCode: SetExitCode): Command;
5
+ export declare function createCompletionCandidatesCommand(context: CommandContext, setExitCode: SetExitCode): Command;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/completion/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,OAAO,EAAqB,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAShD,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,WAAW,GACzB,OAAO,CAWT;AAED,wBAAgB,iCAAiC,CAC7C,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,WAAW,GACzB,OAAO,CAUT"}
@@ -0,0 +1,23 @@
1
+ import { Argument, Command } from "commander";
2
+ import { runCompletion, runCompletionCandidates, } from "./action.js";
3
+ const supportedShells = ["bash", "zsh", "fish", "powershell"];
4
+ export function createCompletionCommand(context, setExitCode) {
5
+ return new Command("completion")
6
+ .description("Generate shell completion scripts")
7
+ .addArgument(new Argument("<shell>", "shell to generate completion for").choices(supportedShells))
8
+ .action((shell) => {
9
+ setExitCode(runCompletion(shell, context));
10
+ });
11
+ }
12
+ export function createCompletionCandidatesCommand(context, setExitCode) {
13
+ return new Command("_complete")
14
+ .argument("[words...]")
15
+ .allowUnknownOption(true)
16
+ .action((words, _options, command) => {
17
+ if (!command.parent) {
18
+ throw new Error("Completion command is not attached to the CLI root.");
19
+ }
20
+ setExitCode(runCompletionCandidates(command.parent, words, context));
21
+ });
22
+ }
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/completion/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAqB,MAAM,WAAW,CAAC;AAGjE,OAAO,EACH,aAAa,EACb,uBAAuB,GAE1B,MAAM,aAAa,CAAC;AAErB,MAAM,eAAe,GAAsB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;AAEjF,MAAM,UAAU,uBAAuB,CACnC,OAAuB,EACvB,WAAwB;IAExB,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC;SAC3B,WAAW,CAAC,mCAAmC,CAAC;SAChD,WAAW,CACR,IAAI,QAAQ,CAAC,SAAS,EAAE,kCAAkC,CAAC,CAAC,OAAO,CAC/D,eAAe,CAClB,CACJ;SACA,MAAM,CAAC,CAAC,KAAsB,EAAE,EAAE;QAC/B,WAAW,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC7C,OAAuB,EACvB,WAAwB;IAExB,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;SAC1B,QAAQ,CAAC,YAAY,CAAC;SACtB,kBAAkB,CAAC,IAAI,CAAC;SACxB,MAAM,CAAC,CAAC,KAAe,EAAE,QAAsB,EAAE,OAAgB,EAAE,EAAE;QAClE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QAC3E,CAAC;QACD,WAAW,CAAC,uBAAuB,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CliConfig, CommandContext } from "../../types.js";
2
+ export declare function runConfigPath(context: CommandContext): number;
3
+ export declare function runConfigShow(configPath: string, config: CliConfig, json: boolean, context: CommandContext): number;
4
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/commands/config/action.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAkB,MAAM,gBAAgB,CAAC;AAEhF,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAG7D;AAED,wBAAgB,aAAa,CACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,cAAc,GACxB,MAAM,CAuBR"}