cdd-cli 3.0.0 → 3.1.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 (66) hide show
  1. package/.github/workflows/ci.yml +29 -0
  2. package/CHANGELOG.md +27 -0
  3. package/CODE_OF_CONDUCT.md +12 -0
  4. package/CONTRIBUTING.md +22 -0
  5. package/LICENSE +23 -0
  6. package/README.md +73 -161
  7. package/SECURITY.md +5 -0
  8. package/babel.config.cjs +6 -0
  9. package/dist/App.js +38 -24
  10. package/dist/cdd.bundle.js +8 -0
  11. package/dist/components/ContainerCreationPrompt.js +48 -0
  12. package/dist/components/ContainerCreator.js +81 -0
  13. package/dist/components/ContainerList.js +24 -4
  14. package/dist/components/ContainerRow.js +66 -13
  15. package/dist/components/ContainerSection.js +14 -0
  16. package/dist/components/Footer.js +10 -0
  17. package/dist/components/PromptField.js +20 -0
  18. package/dist/components/UsageMenu.js +8 -0
  19. package/dist/helpers/actionHelpers.js +0 -1
  20. package/dist/helpers/dockerActions.js +13 -0
  21. package/dist/helpers/dockerService/dockerService.js +5 -0
  22. package/dist/helpers/dockerService/serviceComponents/containerActions.js +163 -0
  23. package/dist/helpers/dockerService/serviceComponents/containerList.js +57 -0
  24. package/dist/helpers/dockerService/serviceComponents/containerLogs.js +24 -0
  25. package/dist/helpers/dockerService/serviceComponents/containerStats.js +50 -0
  26. package/dist/helpers/dockerService/serviceComponents/imageUtils.js +52 -0
  27. package/dist/helpers/dockerService.js +111 -0
  28. package/dist/helpers/validationHelpers.js +26 -0
  29. package/dist/hooks/creation/useContainerActions.js +171 -0
  30. package/dist/hooks/creation/useContainerCreation.js +141 -0
  31. package/dist/hooks/creation/useLogsViewer.js +62 -0
  32. package/dist/hooks/useContainers.js +11 -1
  33. package/dist/hooks/useControls.js +298 -78
  34. package/dist/hooks/useLogsStream.js +1 -1
  35. package/dist/index.js +11 -0
  36. package/esbuild.config.cjs +11 -0
  37. package/jest.config.cjs +6 -0
  38. package/package.json +10 -6
  39. package/src/App.jsx +43 -26
  40. package/src/components/ContainerCreationPrompt.jsx +37 -0
  41. package/src/components/ContainerList.jsx +23 -6
  42. package/src/components/ContainerRow.jsx +36 -19
  43. package/src/components/ContainerSection.jsx +10 -0
  44. package/src/components/Footer.jsx +10 -0
  45. package/src/components/PromptField.jsx +18 -0
  46. package/src/components/UsageMenu.jsx +17 -0
  47. package/src/helpers/actionHelpers.js +0 -1
  48. package/src/helpers/dockerService/dockerService.js +3 -0
  49. package/src/helpers/dockerService/serviceComponents/containerActions.js +52 -0
  50. package/src/helpers/dockerService/serviceComponents/containerList.js +26 -0
  51. package/src/helpers/dockerService/serviceComponents/containerLogs.js +19 -0
  52. package/src/helpers/dockerService/serviceComponents/containerStats.js +34 -0
  53. package/src/helpers/dockerService/serviceComponents/imageUtils.js +21 -0
  54. package/src/helpers/validationHelpers.js +16 -0
  55. package/src/hooks/creation/useContainerActions.js +68 -0
  56. package/src/hooks/creation/useContainerCreation.js +104 -0
  57. package/src/hooks/creation/useLogsViewer.js +50 -0
  58. package/src/hooks/useContainers.js +11 -1
  59. package/src/hooks/useControls.js +176 -55
  60. package/src/hooks/useLogsStream.js +1 -1
  61. package/src/index.js +13 -0
  62. package/test/validationHelpers.test.js +28 -0
  63. package/PLAN_KEYBINDINGS_Y_REALTIME.md +0 -260
  64. package/src/components/StatsViewer.jsx +0 -0
  65. package/src/helpers/dockerActions.js +0 -39
  66. package/src/helpers/dockerService.js +0 -88
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ test-and-build:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Setup Node.js
17
+ uses: actions/setup-node@v4
18
+ with:
19
+ node-version: '18'
20
+ cache: 'npm'
21
+
22
+ - name: Install dependencies
23
+ run: npm ci
24
+
25
+ - name: Run tests
26
+ run: npm test
27
+
28
+ - name: Build
29
+ run: npm run build
package/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
+
7
+ ## [3.1.0] - 2025-10-16
8
+
9
+ ### Added
10
+
11
+ - Modularized hooks: `useContainerCreation`, `useContainerActions`, `useLogsViewer`.
12
+ - Validation helpers and unit tests for port validation.
13
+ - CI workflow (GitHub Actions) and README improvements.
14
+
15
+ ### Changed
16
+
17
+ - Container creation UX: English feedback messages, mandatory/validated port input, DB image warnings.
18
+ - Added erase action (key `E`) with confirmation to delete containers.
19
+ - Normalized source imports to include explicit `.js`/`.jsx` extensions for ESM compatibility.
20
+
21
+ ### Fixed
22
+
23
+ - Various runtime & build issues after modularization (import fixes, exposing container action functions, creation flow wiring).
24
+
25
+ ## [Unreleased]
26
+
27
+ - Incoming fixes and smaller tests / docs updates
@@ -0,0 +1,12 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ This project follows the Contributor Covenant Code of Conduct. By participating, you agree to abide by its terms.
4
+
5
+ Please see https://www.contributor-covenant.org/ for the full text.
6
+ ## Code of Conduct
7
+
8
+ This project follows the [Contributor Covenant](https://www.contributor-covenant.org/).
9
+
10
+ Be respectful, inclusive, and kind. Harassment, discrimination, or abusive language will not be tolerated.
11
+
12
+ If you experience or witness unacceptable behavior, please contact the maintainers.
@@ -0,0 +1,22 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in contributing! Please follow these guidelines:
4
+
5
+ - Fork the repository and create a feature branch.
6
+ - Keep changes small and focused.
7
+ - Add or update tests for new behaviors.
8
+ - Run `npm test` and `npm run build` before opening a PR.
9
+ - Use conventional commits where possible.
10
+
11
+ For any design or large changes, open an issue first to discuss.
12
+ ## Contributing to CDD-CLI
13
+
14
+ Thanks for your interest in contributing! A few guidelines to make collaboration smooth:
15
+
16
+ - Fork the repo and create a branch for your feature/fix: `git checkout -b feat/my-feature`.
17
+ - Write tests for any new behavior and ensure existing tests pass: `npm test`.
18
+ - Follow the existing code style and run `npm run build` before opening a PR.
19
+ - Keep PRs focused and describe motivation and changes.
20
+ - Tag reviewers and link related issues.
21
+
22
+ We appreciate clear, well-tested contributions.
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ SPDX-License-Identifier: MIT
4
+
5
+ Copyright (c) 2025 caertos
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/README.md CHANGED
@@ -1,196 +1,106 @@
1
- ## Instrucciones avanzadas
1
+ ## CDD-CLI — Docker Dashboard (Terminal)
2
2
 
3
- ### Desarrollo local
4
- 1. Clona el repositorio:
5
- ```bash
6
- git clone https://github.com/caertos/cdd.git
7
- cd cdd
8
- ```
9
- 2. Instala dependencias:
10
- ```bash
11
- npm install
12
- ```
13
- 3. Transpila el código fuente:
14
- ```bash
15
- npm run build
16
- ```
17
- 4. Ejecuta el CLI localmente:
18
- ```bash
19
- node dist/index.js
20
- ```
21
- 5. Prueba el comando global localmente:
22
- ```bash
23
- npm link
24
- cdd
25
- ```
26
-
27
- ### Testing y troubleshooting
28
- - Si modificas componentes, recuerda siempre ejecutar `npm run build` antes de probar.
29
- - Si tienes problemas con permisos de Docker, ejecuta la terminal como administrador o usa `sudo`.
30
- - Para limpiar la instalación global:
31
- ```bash
32
- npm uninstall -g cdd-cli
33
- ```
3
+ <p align="center">
4
+ <img src="https://img.shields.io/npm/v/cdd-cli?color=blue&label=npm%20package" alt="npm version"/>
5
+ <img src="https://img.shields.io/npm/dt/cdd-cli?color=green&label=downloads" alt="npm downloads"/>
6
+ <a href="https://github.com/caertos/cdd/actions/workflows/ci.yml">
7
+ <img src="https://github.com/caertos/cdd/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI status" />
8
+ </a>
9
+ </p>
34
10
 
35
- ### Contribución
36
- 1. Haz un fork del repositorio y crea una rama para tu feature o fix.
37
- 2. Asegúrate de que tu código pase el build y funcione correctamente.
38
- 3. Haz un Pull Request con una descripción clara de tus cambios.
11
+ Short, bilingual README with quickstart, development and tests.
39
12
 
40
13
  ---
41
- ## Advanced instructions
42
14
 
43
- ### Local development
44
- 1. Clone the repository:
45
- ```bash
46
- git clone https://github.com/caertos/cdd.git
47
- cd cdd
48
- ```
49
- 2. Install dependencies:
50
- ```bash
51
- npm install
52
- ```
53
- 3. Transpile the source code:
54
- ```bash
55
- npm run build
56
- ```
57
- 4. Run the CLI locally:
58
- ```bash
59
- node dist/index.js
60
- ```
61
- 5. Test the global command locally:
62
- ```bash
63
- npm link
64
- cdd
65
- ```
15
+ ## Quick start (local)
16
+
17
+ 1. Clone the repo and install dependencies:
18
+
19
+ ```bash
20
+ git clone https://github.com/caertos/cdd.git
21
+ cd cdd
22
+ npm install
23
+ ```
24
+
25
+ 2. Build and run locally:
26
+
27
+ ```bash
28
+ npm run build
29
+ node dist/index.js
30
+ ```
66
31
 
67
- ### Testing and troubleshooting
68
- - If you modify components, always run `npm run build` before testing.
69
- - If you have Docker permission issues, run your terminal as administrator or use `sudo`.
70
- - To clean up the global install:
71
- ```bash
72
- npm uninstall -g cdd-cli
73
- ```
32
+ 3. To test the CLI as a globally available command during development:
74
33
 
75
- ### Contributing
76
- 1. Fork the repository and create a branch for your feature or fix.
77
- 2. Make sure your code builds and works correctly.
78
- 3. Open a Pull Request with a clear description of your changes.
34
+ ```bash
35
+ npm link
36
+ cdd
37
+ ```
79
38
 
80
39
  ---
81
40
 
41
+ ## Usage (interactive)
82
42
 
83
- <p align="center">
84
- <img src="https://img.shields.io/npm/v/cdd-cli?color=blue&label=npm%20package" alt="npm version"/>
85
- <img src="https://img.shields.io/npm/dt/cdd-cli?color=green&label=descargas" alt="npm downloads"/>
86
- </p>
43
+ - Use ↑/↓ to navigate containers.
44
+ - I: start selected container
45
+ - P: stop selected container
46
+ - R: restart selected container
47
+ - C: create container (interactive prompt)
48
+ - L: view logs for selected container
49
+ - E: erase (remove) selected container (confirmation required)
50
+ - Q: quit
87
51
 
88
- # 🐳 CDD-CLI Docker Dashboard en la Terminal
89
- [English version below]
52
+ The dashboard auto-refreshes container list every few seconds.
90
53
 
91
54
  ---
92
55
 
93
- ## Ejemplo visual
94
-
95
- ```text
96
- ╭────────────────────────────────────────────────────────────────────────────╮
97
- │ 🐳 CDD — CLI Docker Dashboard 2 containers found │
98
- │ │
99
- mysql-dev mysql:latest 🟢 RUNNING │
100
- CPU: ░░░░░░░░░░ 0.1% MEM: ░░░░░░░░░░ 4.9% │
101
- │ │
102
- │ redis-test redis:alpine 🔴 EXITED │
103
- │ │
104
- │ Press Ctrl+C to exit │
105
- │ Crafted by Carlos Cochero • 2025 │
106
- ╰────────────────────────────────────────────────────────────────────────────╯
107
- ```
108
- # 🐳 CDD-CLI — Docker Dashboard in your Terminal
109
-
110
- ## Visual example
111
-
112
- ```text
113
- ╭────────────────────────────────────────────────────────────────────────────╮
114
- │ 🐳 CDD — CLI Docker Dashboard 2 containers found │
115
- │ │
116
- │ mysql-dev mysql:latest 🟢 RUNNING │
117
- │ CPU: ░░░░░░░░░░ 0.1% MEM: ░░░░░░░░░░ 4.9% │
118
- │ │
119
- │ redis-test redis:alpine 🔴 EXITED │
120
- │ │
121
- │ Press Ctrl+C to exit │
122
- │ Crafted by Carlos Cochero • 2025 │
123
- ╰────────────────────────────────────────────────────────────────────────────╯
56
+ ## Development
57
+
58
+ - Node.js >= 18 is recommended.
59
+ - To run the app from source during development:
60
+
61
+ ```bash
62
+ npm install
63
+ npm run build
64
+ node dist/index.js
124
65
  ```
125
66
 
126
- [English version below]
67
+ If you change source files, re-run `npm run build` before running the CLI.
127
68
 
128
69
  ---
129
70
 
130
- ## Descripción
131
- CDD-CLI es una herramienta de línea de comandos (CLI) multiplataforma que te permite monitorear y visualizar en tiempo real el estado de tus contenedores Docker directamente desde la terminal, usando una interfaz moderna y colorida basada en React e Ink.
71
+ ## Tests
132
72
 
133
- - Visualiza todos los contenedores activos y detenidos.
134
- - Muestra nombre, imagen, estado, puertos y estadísticas de CPU/MEM.
135
- - Actualización automática cada 2 segundos.
136
- - Interfaz amigable, con colores y emojis.
137
- - Compatible con Linux, macOS y Windows (bash, cmd, PowerShell).
73
+ We use Jest for unit tests. Run:
138
74
 
139
- ## Instalación global
140
-
141
- 1. Asegúrate de tener Node.js (v18+) y Docker instalados y en ejecución.
142
- 2. Instala el CLI globalmente desde npm:
143
- ```bash
144
- npm install -g cdd-cli
145
- ```
146
- 3. Ejecuta el dashboard desde cualquier terminal:
147
- ```bash
148
- cdd
149
- ```
75
+ ```bash
76
+ npm test
77
+ ```
150
78
 
151
- ## Uso
152
- - Al ejecutar `cdd`, verás una tabla con todos tus contenedores Docker.
153
- - Los contenedores en ejecución muestran estadísticas de CPU y memoria en tiempo real.
154
- - Usa `Ctrl+C` para salir.
79
+ Tests are located in `test/` and cover utility helpers.
155
80
 
156
- ## Funcionalidades principales
157
- - 🐳 Visualización clara y compacta de todos los contenedores.
158
- - 🔄 Refresco automático de datos.
159
- - 📊 Estadísticas de uso de recursos para contenedores activos.
160
- - 🎨 Interfaz visual con colores y emojis para estados.
161
- - 👤 Autor: Carlos Cochero (2025)
81
+ ---
162
82
 
163
- ## Requisitos
164
- - Node.js >= 18
165
- - Docker instalado y corriendo (el CLI se conecta al socket local de Docker)
83
+ ## Contributing
166
84
 
167
- ## Troubleshooting
168
- - Si no ves contenedores, asegúrate de que Docker esté corriendo y tu usuario tenga permisos para acceder al socket Docker.
169
- - Si tienes problemas con la instalación global, prueba con `sudo` (Linux/macOS) o ejecuta la terminal como administrador (Windows).
85
+ 1. Fork the repo and create a feature branch.
86
+ 2. Add tests for new behavior.
87
+ 3. Ensure `npm test` and `npm run build` pass.
88
+ 4. Open a Pull Request with a clear description.
170
89
 
171
90
  ---
172
91
 
173
- # 🐳 CDD-CLI — Docker Dashboard in your Terminal
92
+ ## Troubleshooting
93
+
94
+ - If you don't see containers, ensure Docker is running and that your user has access to the Docker socket.
95
+ - If Docker permissions are required, run the CLI with `sudo` (Linux/macOS) or as Administrator (Windows).
96
+ - The project generates `dist/` — keep it out of version control (it's in .gitignore).
174
97
 
175
- ## Description
176
- CDD-CLI is a cross-platform command-line tool (CLI) to monitor and visualize your Docker containers in real time, right from your terminal, using a modern React+Ink interface.
98
+ ---
177
99
 
178
- - See all running and stopped containers.
179
- - Shows name, image, state, ports, and CPU/MEM stats.
180
- - Auto-refresh every 2 seconds.
181
- - Friendly, colorful, emoji-rich UI.
182
- - Works on Linux, macOS, and Windows (bash, cmd, PowerShell).
100
+ ## License
183
101
 
184
- ## Global installation
102
+ This project is MIT/ISC licensed (see `LICENSE`).
185
103
 
186
- 1. Make sure you have Node.js (v18+) and Docker installed and running.
187
- 2. Install the CLI globally from npm:
188
- ```bash
189
- npm install -g cdd-cli
190
- ```
191
- 3. Run the dashboard from any terminal:
192
- ```bash
193
- cdd
194
104
  ```
195
105
 
196
106
  ## Usage
@@ -200,8 +110,10 @@ CDD-CLI is a cross-platform command-line tool (CLI) to monitor and visualize you
200
110
 
201
111
  ## Main features
202
112
  - 🐳 Clear, compact visualization of all containers.
203
- - 🔄 Automatic data refresh.
113
+ - 🔄 Automatic data refresh (every 2 seconds).
114
+ - ⌨️ Keyboard shortcuts for fast actions (navigate, start, stop, logs, quit).
204
115
  - 📊 Live resource usage stats for running containers.
116
+ - 🪵 Real-time log streaming for selected containers.
205
117
  - 🎨 Visual interface with colors and emojis for states.
206
118
  - 👤 Author: Carlos Cochero (2025)
207
119
 
package/SECURITY.md ADDED
@@ -0,0 +1,5 @@
1
+ # Security
2
+
3
+ If you discover a security vulnerability, please report it privately to the repository owner.
4
+
5
+ Do not disclose vulnerabilities publicly until they are resolved.
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ presets: [
3
+ ['@babel/preset-env', { targets: { node: 'current' } }],
4
+ '@babel/preset-react'
5
+ ]
6
+ };
package/dist/App.js CHANGED
@@ -1,21 +1,40 @@
1
+ /**
2
+ * Main React component for the CDD CLI UI.
3
+ * Componente principal de React para la UI del CLI CDD.
4
+ *
5
+ * @component
6
+ * @returns {JSX.Element} The rendered app / La app renderizada
7
+ * @example
8
+ * // EN: Render the app
9
+ * // ES: Renderizar la app
10
+ * <App />
11
+ */
1
12
  import React from "react";
2
13
  import { Box, Text, Spacer } from "ink";
3
14
  import { useContainers } from "./hooks/useContainers.js";
4
15
  import { useControls } from "./hooks/useControls.js";
5
- import ContainerList from "./components/ContainerList.js";
6
- import MessageFeedback from "./components/MessageFeedback.js";
7
- import Header from "./components/Header.js";
8
- import LogViewer from "./components/LogViewer.js";
16
+ import ContainerSection from "./components/ContainerSection.jsx";
17
+ import MessageFeedback from "./components/MessageFeedback.jsx";
18
+ import Header from "./components/Header.jsx";
19
+ import LogViewer from "./components/LogViewer.jsx";
20
+ import ContainerCreationPrompt from "./components/ContainerCreationPrompt.jsx";
21
+ import UsageMenu from "./components/UsageMenu.jsx";
22
+ import Footer from "./components/Footer.jsx";
9
23
  export default function App() {
10
24
  var _useContainers = useContainers(),
11
25
  containers = _useContainers.containers;
12
- var _useControls = useControls(containers),
13
- selected = _useControls.selected,
14
- message = _useControls.message,
15
- messageColor = _useControls.messageColor,
16
- showLogs = _useControls.showLogs,
17
- logs = _useControls.logs,
18
- exitLogs = _useControls.exitLogs;
26
+ var controls = useControls(containers);
27
+ if (controls.creatingContainer) {
28
+ return /*#__PURE__*/React.createElement(ContainerCreationPrompt, {
29
+ step: controls.creationStep,
30
+ imageName: controls.imageNameInput,
31
+ containerName: controls.containerNameInput,
32
+ portInput: controls.portInput,
33
+ envInput: controls.envInput,
34
+ message: controls.message,
35
+ messageColor: controls.messageColor
36
+ });
37
+ }
19
38
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Box, {
20
39
  flexDirection: "column",
21
40
  borderStyle: "round",
@@ -23,20 +42,15 @@ export default function App() {
23
42
  padding: 1
24
43
  }, /*#__PURE__*/React.createElement(Header, {
25
44
  count: containers.length
26
- }), /*#__PURE__*/React.createElement(Text, null, " "), containers.length === 0 ? /*#__PURE__*/React.createElement(Text, null, "No containers found") : /*#__PURE__*/React.createElement(ContainerList, {
45
+ }), /*#__PURE__*/React.createElement(Text, null, " "), /*#__PURE__*/React.createElement(ContainerSection, {
27
46
  containers: containers,
28
- selected: selected
47
+ selected: controls.selected
29
48
  }), /*#__PURE__*/React.createElement(Spacer, null), /*#__PURE__*/React.createElement(MessageFeedback, {
30
- message: message,
31
- color: messageColor
32
- }), /*#__PURE__*/React.createElement(Text, null, "Use \u2191/\u2193 for navigation"), /*#__PURE__*/React.createElement(Text, null, "\u2022I to initiate selected container"), /*#__PURE__*/React.createElement(Text, null, "\u2022P to stop selected container"), /*#__PURE__*/React.createElement(Text, null, "\u2022L to view logs of selected container"), /*#__PURE__*/React.createElement(Text, null, "\u2022Q to quit"), /*#__PURE__*/React.createElement(Box, {
33
- justifyContent: "flex-end",
34
- width: "100%"
35
- }, /*#__PURE__*/React.createElement(Text, {
36
- dimColor: true
37
- }, "Crafted by Carlos Cochero \u2022 2025"))), showLogs && /*#__PURE__*/React.createElement(LogViewer, {
38
- logs: logs,
39
- onExit: exitLogs,
40
- container: containers[selected]
49
+ message: controls.message,
50
+ color: controls.messageColor
51
+ }), /*#__PURE__*/React.createElement(UsageMenu, null), /*#__PURE__*/React.createElement(Footer, null)), controls.showLogs && /*#__PURE__*/React.createElement(LogViewer, {
52
+ logs: controls.logs,
53
+ onExit: controls.exitLogs,
54
+ container: containers[controls.selected]
41
55
  }));
42
56
  }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import Rt from"react";import{render as $t}from"ink";import x from"react";import{Box as Lt,Text as jt,Spacer as Dt}from"ink";import{useState as tt,useEffect as rt}from"react";import et from"dockerode";var f=new et({socketPath:"/var/run/docker.sock"});async function Ee(){return(await f.listContainers({all:!0})).map(e=>({id:e.Id,name:e.Names[0].replace("/",""),image:e.Image,state:e.State,status:e.Status,ports:[...new Set(e.Ports.filter(r=>r.PublicPort).map(r=>`${r.PublicPort}:${r.PrivatePort}`))]}))}function Ie(){let[t,e]=tt([]);return rt(()=>{let r=async()=>e(await Ee());r();let o=setInterval(r,3e3);return()=>clearInterval(o)},[]),{containers:t}}import{useState as T,useRef as ot}from"react";import{useInput as nt}from"ink";async function Oe(t){return(await f.listImages()).some(r=>(r.RepoTags||[]).includes(t)||(r.RepoDigests||[]).some(o=>o.includes(t)))}async function Be(t){await new Promise((e,r)=>{f.pull(t,(o,n)=>{if(o)return r(new Error("Error al hacer pull de la imagen: "+o.message));f.modem.followProgress(n,s=>{s?r(new Error("Error durante el pull: "+s.message)):e()})})})}async function ve(t,e={}){let r;try{r=await Oe(t)}catch(n){throw new Error("Error al listar im\xE1genes locales: "+n.message)}if(!r)try{await Be(t)}catch(n){throw new Error("No se pudo descargar la imagen: "+n.message)}let o={Image:t,Tty:!0,...e};try{let n=await f.createContainer(o);return n.id||n.Id}catch(n){throw new Error("Error al crear el contenedor: "+n.message)}}async function Se(t){await f.getContainer(t).start()}async function Ae(t){await f.getContainer(t).stop()}async function Ne(t){await f.getContainer(t).restart()}function Pe(t,e,r,o){f.getContainer(t).logs({follow:!0,stdout:!0,stderr:!0,tail:100},(s,i)=>{if(s){o?.(s);return}i.on("data",u=>e?.(u.toString())),i.on("end",()=>r?.()),i.on("error",u=>o?.(u))})}async function Y({containers:t,selected:e,actionFn:r,actionLabel:o,setMessage:n,setMessageColor:s,stateCheck:i}){let u=t[e];if(u){if(i&&i(u)){n(i(u)),s("red"),setTimeout(()=>n(""),2e3);return}n(`${o} container...`),s("green");try{await r(u.id),n(`${o} container...`),s("green"),setTimeout(()=>n(""),3e3)}catch{n(`Failed to ${o.toLowerCase()} container.`),s("red"),setTimeout(()=>n(""),3e3)}}}import{spawn as Fe}from"child_process";function _e({setMessage:t,setMessageColor:e,message:r="Exiting...",color:o="yellow",delay:n=1500}){t(r),e(o),setTimeout(()=>{t(""),process.platform==="win32"?Fe("cmd",["/c","cls"],{stdio:"inherit"}):Fe("clear",[],{stdio:"inherit"}),process.exit()},n)}function Me(t=[]){let[e,r]=T(0),[o,n]=T(""),[s,i]=T("yellow"),[u,w]=T(!1),[E,b]=T([]),[m,C]=T(!1),[B,F]=T(""),[z,G]=T(""),[Q,_]=T(""),[X,M]=T(""),[p,S]=T(0),J=ot(null),U=t.length,Z=()=>{w(!1),b([]),J.current&&(J.current.destroy?.(),J.current=null)};return nt(async(d,V)=>{if(u){(d==="q"||V.escape)&&Z();return}if(m){if(V.escape){C(!1),F(""),G(""),_(""),M(""),S(0),n("Creaci\xF3n cancelada"),i("yellow");return}if(d==="\r"){if(p===0){if(!B.trim()){n("El nombre de la imagen no puede estar vac\xEDo."),i("red");return}S(1),n("Opcional: Ingresa el nombre del contenedor o deja vac\xEDo y presiona Enter"),i("yellow");return}if(p===1){S(2),n("Opcional: Ingresa puertos (formato 8080:80,443:443) o deja vac\xEDo y presiona Enter"),i("yellow");return}if(p===2){S(3),n("Opcional: Ingresa variables de entorno (formato VAR1=val1,VAR2=val2) o deja vac\xEDo y presiona Enter"),i("yellow");return}if(p===3){let a={};if(z.trim()&&(a.name=z.trim()),Q.trim()){let h=Q.split(",").map(ee=>ee.trim()).filter(Boolean);a.ExposedPorts={},a.HostConfig={PortBindings:{}},h.forEach(ee=>{let[we,te]=ee.split(":");we&&te&&(a.ExposedPorts[`${te}/tcp`]={},a.HostConfig.PortBindings[`${te}/tcp`]=[{HostPort:we}])})}X.trim()&&(a.Env=X.split(",").map(h=>h.trim()).filter(Boolean)),n("Creando contenedor..."),i("yellow");try{let h=await ve(B.trim(),a);n(`Contenedor creado con ID: ${h}`),i("green")}catch(h){n(`Error: ${h.message}`),i("red")}setTimeout(()=>{C(!1),F(""),G(""),_(""),M(""),S(0)},2500);return}}else d==="\x7F"?(p===0&&F(a=>a.slice(0,-1)),p===1&&G(a=>a.slice(0,-1)),p===2&&_(a=>a.slice(0,-1)),p===3&&M(a=>a.slice(0,-1))):(p===0&&F(a=>a+d),p===1&&G(a=>a+d),p===2&&_(a=>a+d),p===3&&M(a=>a+d));return}if(V.upArrow&&U>0&&r(a=>a===0?U-1:a-1),V.downArrow&&U>0&&r(a=>a===U-1?0:a+1),d==="q"){_e({setMessage:n,setMessageColor:i});return}if(d==="i"&&Y({containers:t,selected:e,actionFn:Se,actionLabel:"Starting",setMessage:n,setMessageColor:i,stateCheck:a=>(a.state==="running"||a.status==="running")&&"Container is already running."}),d==="p"&&Y({containers:t,selected:e,actionFn:Ae,actionLabel:"Stopping",setMessage:n,setMessageColor:i,stateCheck:a=>(a.state==="exited"||a.status==="exited"||a.state==="stopped"||a.status==="stopped")&&"Container is already stopped."}),d==="r"&&Y({containers:t,selected:e,actionFn:Ne,actionLabel:"Restarting",setMessage:n,setMessageColor:i}),d==="l"&&t[e])return w(!0),b([]),Pe(t[e].id,a=>b(h=>[...h,...a.split(`
3
+ `).filter(Boolean)]),()=>{},a=>b(h=>[...h,`Error: ${a.message}`])),{selected:e,setSelected:r,message:o,messageColor:s,showLogs:u,logs:E,exitLogs:Z};d==="c"&&(C(!0),F(""),_(""),M(""),S(0),n("Ingresa el nombre de la imagen Docker y presiona Enter"),i("yellow"))}),{selected:e,setSelected:r,message:o,messageColor:s,showLogs:u,logs:E,exitLogs:Z,creatingContainer:m,imageNameInput:B,containerNameInput:z,portInput:Q,envInput:X,creationStep:p}}import D from"react";import{Box as It,Text as Ot}from"ink";import I,{useState as Ke,useEffect as wt}from"react";import{Box as le,Text as j}from"ink";async function ke(t){let r=await f.getContainer(t).stats({stream:!1}),o=r.cpu_stats.cpu_usage.total_usage-r.precpu_stats.cpu_usage.total_usage,n=r.cpu_stats.system_cpu_usage-r.precpu_stats.system_cpu_usage,s=n>0?o/n*100:0,i=r.memory_stats.usage||0,u=r.memory_stats.limit||1,w=i/u*100,E=r.networks?Object.values(r.networks).map(m=>m.rx_bytes).reduce((m,C)=>m+C,0):0,b=r.networks?Object.values(r.networks).map(m=>m.tx_bytes).reduce((m,C)=>m+C,0):0;return{cpuPercent:s.toFixed(1),memPercent:w.toFixed(1),netIO:{rx:E,tx:b}}}import Tt from"react";import{Text as yt}from"ink";var Le=(t=0)=>e=>`\x1B[${e+t}m`,je=(t=0)=>e=>`\x1B[${38+t};5;${e}m`,De=(t=0)=>(e,r,o)=>`\x1B[${38+t};2;${e};${r};${o}m`,l={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}},gr=Object.keys(l.modifier),it=Object.keys(l.color),st=Object.keys(l.bgColor),xr=[...it,...st];function at(){let t=new Map;for(let[e,r]of Object.entries(l)){for(let[o,n]of Object.entries(r))l[o]={open:`\x1B[${n[0]}m`,close:`\x1B[${n[1]}m`},r[o]=l[o],t.set(n[0],n[1]);Object.defineProperty(l,e,{value:r,enumerable:!1})}return Object.defineProperty(l,"codes",{value:t,enumerable:!1}),l.color.close="\x1B[39m",l.bgColor.close="\x1B[49m",l.color.ansi=Le(),l.color.ansi256=je(),l.color.ansi16m=De(),l.bgColor.ansi=Le(10),l.bgColor.ansi256=je(10),l.bgColor.ansi16m=De(10),Object.defineProperties(l,{rgbToAnsi256:{value(e,r,o){return e===r&&r===o?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(r/255*5)+Math.round(o/255*5)},enumerable:!1},hexToRgb:{value(e){let r=/[a-f\d]{6}|[a-f\d]{3}/i.exec(e.toString(16));if(!r)return[0,0,0];let[o]=r;o.length===3&&(o=[...o].map(s=>s+s).join(""));let n=Number.parseInt(o,16);return[n>>16&255,n>>8&255,n&255]},enumerable:!1},hexToAnsi256:{value:e=>l.rgbToAnsi256(...l.hexToRgb(e)),enumerable:!1},ansi256ToAnsi:{value(e){if(e<8)return 30+e;if(e<16)return 90+(e-8);let r,o,n;if(e>=232)r=((e-232)*10+8)/255,o=r,n=r;else{e-=16;let u=e%36;r=Math.floor(e/36)/5,o=Math.floor(u/6)/5,n=u%6/5}let s=Math.max(r,o,n)*2;if(s===0)return 30;let i=30+(Math.round(n)<<2|Math.round(o)<<1|Math.round(r));return s===2&&(i+=60),i},enumerable:!1},rgbToAnsi:{value:(e,r,o)=>l.ansi256ToAnsi(l.rgbToAnsi256(e,r,o)),enumerable:!1},hexToAnsi:{value:e=>l.ansi256ToAnsi(l.hexToAnsi256(e)),enumerable:!1}}),l}var lt=at(),y=lt;import re from"node:process";import ct from"node:os";import Re from"node:tty";function g(t,e=globalThis.Deno?globalThis.Deno.args:re.argv){let r=t.startsWith("-")?"":t.length===1?"-":"--",o=e.indexOf(r+t),n=e.indexOf("--");return o!==-1&&(n===-1||o<n)}var{env:c}=re,q;g("no-color")||g("no-colors")||g("color=false")||g("color=never")?q=0:(g("color")||g("colors")||g("color=true")||g("color=always"))&&(q=1);function ut(){if("FORCE_COLOR"in c)return c.FORCE_COLOR==="true"?1:c.FORCE_COLOR==="false"?0:c.FORCE_COLOR.length===0?1:Math.min(Number.parseInt(c.FORCE_COLOR,10),3)}function mt(t){return t===0?!1:{level:t,hasBasic:!0,has256:t>=2,has16m:t>=3}}function ft(t,{streamIsTTY:e,sniffFlags:r=!0}={}){let o=ut();o!==void 0&&(q=o);let n=r?q:o;if(n===0)return 0;if(r){if(g("color=16m")||g("color=full")||g("color=truecolor"))return 3;if(g("color=256"))return 2}if("TF_BUILD"in c&&"AGENT_NAME"in c)return 1;if(t&&!e&&n===void 0)return 0;let s=n||0;if(c.TERM==="dumb")return s;if(re.platform==="win32"){let i=ct.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in c)return["GITHUB_ACTIONS","GITEA_ACTIONS","CIRCLECI"].some(i=>i in c)?3:["TRAVIS","APPVEYOR","GITLAB_CI","BUILDKITE","DRONE"].some(i=>i in c)||c.CI_NAME==="codeship"?1:s;if("TEAMCITY_VERSION"in c)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(c.TEAMCITY_VERSION)?1:0;if(c.COLORTERM==="truecolor"||c.TERM==="xterm-kitty"||c.TERM==="xterm-ghostty"||c.TERM==="wezterm")return 3;if("TERM_PROGRAM"in c){let i=Number.parseInt((c.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(c.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(c.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(c.TERM)||"COLORTERM"in c?1:s}function $e(t,e={}){let r=ft(t,{streamIsTTY:t&&t.isTTY,...e});return mt(r)}var pt={stdout:$e({isTTY:Re.isatty(1)}),stderr:$e({isTTY:Re.isatty(2)})},Ge=pt;function Ue(t,e,r){let o=t.indexOf(e);if(o===-1)return t;let n=e.length,s=0,i="";do i+=t.slice(s,o)+e+r,s=o+n,o=t.indexOf(e,s);while(o!==-1);return i+=t.slice(s),i}function Ve(t,e,r,o){let n=0,s="";do{let i=t[o-1]==="\r";s+=t.slice(n,i?o-1:o)+e+(i?`\r
4
+ `:`
5
+ `)+r,n=o+1,o=t.indexOf(`
6
+ `,n)}while(o!==-1);return s+=t.slice(n),s}var{stdout:Ye,stderr:qe}=Ge,oe=Symbol("GENERATOR"),A=Symbol("STYLER"),k=Symbol("IS_EMPTY"),We=["ansi","ansi","ansi256","ansi16m"],N=Object.create(null),dt=(t,e={})=>{if(e.level&&!(Number.isInteger(e.level)&&e.level>=0&&e.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let r=Ye?Ye.level:0;t.level=e.level===void 0?r:e.level};var gt=t=>{let e=(...r)=>r.join(" ");return dt(e,t),Object.setPrototypeOf(e,L.prototype),e};function L(t){return gt(t)}Object.setPrototypeOf(L.prototype,Function.prototype);for(let[t,e]of Object.entries(y))N[t]={get(){let r=W(this,ie(e.open,e.close,this[A]),this[k]);return Object.defineProperty(this,t,{value:r}),r}};N.visible={get(){let t=W(this,this[A],!0);return Object.defineProperty(this,"visible",{value:t}),t}};var ne=(t,e,r,...o)=>t==="rgb"?e==="ansi16m"?y[r].ansi16m(...o):e==="ansi256"?y[r].ansi256(y.rgbToAnsi256(...o)):y[r].ansi(y.rgbToAnsi(...o)):t==="hex"?ne("rgb",e,r,...y.hexToRgb(...o)):y[r][t](...o),xt=["rgb","hex","ansi256"];for(let t of xt){N[t]={get(){let{level:r}=this;return function(...o){let n=ie(ne(t,We[r],"color",...o),y.color.close,this[A]);return W(this,n,this[k])}}};let e="bg"+t[0].toUpperCase()+t.slice(1);N[e]={get(){let{level:r}=this;return function(...o){let n=ie(ne(t,We[r],"bgColor",...o),y.bgColor.close,this[A]);return W(this,n,this[k])}}}}var bt=Object.defineProperties(()=>{},{...N,level:{enumerable:!0,get(){return this[oe].level},set(t){this[oe].level=t}}}),ie=(t,e,r)=>{let o,n;return r===void 0?(o=t,n=e):(o=r.openAll+t,n=e+r.closeAll),{open:t,close:e,openAll:o,closeAll:n,parent:r}},W=(t,e,r)=>{let o=(...n)=>Ct(o,n.length===1?""+n[0]:n.join(" "));return Object.setPrototypeOf(o,bt),o[oe]=t,o[A]=e,o[k]=r,o},Ct=(t,e)=>{if(t.level<=0||!e)return t[k]?"":e;let r=t[A];if(r===void 0)return e;let{openAll:o,closeAll:n}=r;if(e.includes("\x1B"))for(;r!==void 0;)e=Ue(e,r.close,r.open),r=r.parent;let s=e.indexOf(`
7
+ `);return s!==-1&&(e=Ve(e,n,o,s)),o+e+n};Object.defineProperties(L.prototype,N);var ht=L(),Br=L({level:qe?qe.level:0});var P=ht;function ae({cpu:t,mem:e}){let r=He(t),o=He(e);return Tt.createElement(yt,null,"CPU: ",r," ",se(t),"% MEM: ",o," ",se(e),"%")}function He(t){let e=Math.round(t/10),r=10-e,o="\u2593".repeat(e)+"\u2591".repeat(r);return se(t,o)}function se(t,e=t.toString()){return t<50?P.greenBright(e):t<80?P.yellowBright(e):P.redBright(e)}var Et=t=>t==="running"?{text:"\u{1F7E2} RUNNING",color:"green"}:t==="exited"?{text:"\u{1F534} EXITED",color:"red"}:t==="paused"?{text:"\u{1F7E0} PAUSED",color:"yellow"}:{text:t.toUpperCase(),color:"gray"};function ce({container:t}){let{id:e,name:r,image:o,state:n}=t,[s,i]=Ke({cpuPercent:0,memPercent:0,netIO:{rx:0,tx:0}}),u=m=>!m||m.length===0?"":Array.isArray(m)?m.map((C,B)=>`\u{1F517} ${C}`).join(" "):`\u{1F517} ${m}`,[w,E]=Ke("");wt(()=>{if(n!=="running")return;let m=async()=>{try{let B=await ke(e);i(B),E("")}catch{i({cpuPercent:0,memPercent:0,netIO:{rx:0,tx:0}}),E("No se pudo obtener stats")}};m();let C=setInterval(m,1500);return()=>clearInterval(C)},[e,n]);let b=Et(n);return I.createElement(le,{flexDirection:"column",marginBottom:1},I.createElement(le,null,I.createElement(j,{color:"cyan"},r.padEnd(20))," ",I.createElement(j,{color:"gray"},o.padEnd(20))," ",I.createElement(j,{color:b.color},b.text)," ",I.createElement(j,{color:"yellow"},u(t.ports))),n==="running"&&I.createElement(le,{marginLeft:2},I.createElement(ae,{cpu:parseFloat(s.cpuPercent),mem:parseFloat(s.memPercent)}),w&&I.createElement(j,{color:"red"},w)))}function ue({containers:t,selected:e}){return D.createElement(D.Fragment,null,t.map((r,o)=>D.createElement(It,{key:r.id,flexDirection:"row",alignItems:"center"},D.createElement(Ot,{color:o===e?"green":void 0},o===e?"\u27A4":" "),D.createElement(ce,{container:r,isSelected:o===e}))))}import ze from"react";import{Text as Bt}from"ink";function me({containers:t,selected:e}){return t.length===0?ze.createElement(Bt,null,"No containers found"):ze.createElement(ue,{containers:t,selected:e})}import Qe from"react";import{Box as vt,Text as St}from"ink";function fe({message:t,color:e}){return t?Qe.createElement(vt,{marginBottom:1},Qe.createElement(St,{color:e},t)):null}import H from"react";import{Box as At,Text as pe}from"ink";function de({count:t}){return H.createElement(At,{justifyContent:"space-between"},H.createElement(pe,{color:"cyanBright"},"\u{1F433} ",P.bold("CDD"),H.createElement(pe,{color:"gray"}," \u2014 CLI Docker Dashboard")),H.createElement(pe,{color:"gray"},t," container",t===1?"":"s"," found"))}import R from"react";import{Text as ge,useInput as Nt}from"ink";function xe({logs:t,onExit:e,container:r}){Nt((n,s)=>{s.escape&&e()});let o=t.slice(-15);return R.createElement(R.Fragment,null,R.createElement(ge,{color:"green"},r?.name||"Container"," logs, press ESC to exit"),o.length===0?R.createElement(ge,{dimColor:!0},"No logs..."):o.map((n,s)=>R.createElement(ge,{key:s},n)))}import K from"react";import{Box as Pt,Text as Ft}from"ink";import $ from"react";import{Text as be}from"ink";function Xe({label:t,value:e,required:r}){let o=r&&!e.trim();return $.createElement($.Fragment,null,$.createElement(be,null,t),$.createElement(be,{color:o?"red":"cyan"},e,"_"))}function Je({message:t,color:e}){return t?$.createElement(be,{color:e||"yellow"},t):null}function Ce(t){let{step:e,imageName:r,containerName:o,portInput:n,envInput:s,message:i,messageColor:u}=t,w=[{label:"Nombre de la imagen Docker:",value:r,required:!0},{label:"Nombre del contenedor (opcional):",value:o,required:!1},{label:"Puertos (opcional, formato 8080:80,443:443):",value:n,required:!1},{label:"Variables de entorno (opcional, formato VAR1=val1,VAR2=val2):",value:s,required:!1}],{label:E,value:b,required:m}=w[e]||{};return K.createElement(Pt,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",padding:1},K.createElement(Xe,{label:E,value:b,required:m}),K.createElement(Je,{message:i,color:u}),K.createElement(Ft,{dimColor:!0},"Presiona Enter para continuar, Escape para cancelar"))}import O from"react";import{Box as _t,Text as v}from"ink";function he(){return O.createElement(_t,{flexDirection:"column",marginTop:1},O.createElement(v,null,"Use \u2191/\u2193 for navigation"),O.createElement(v,null,"\u2022I to initiate selected container"),O.createElement(v,null,"\u2022P to stop selected container"),O.createElement(v,null,"\u2022R to restart selected container"),O.createElement(v,null,"\u2022C to create a container"),O.createElement(v,null,"\u2022L to view logs of selected container"),O.createElement(v,null,"\u2022Q to quit"))}import Ze from"react";import{Box as Mt,Text as kt}from"ink";function Te(){return Ze.createElement(Mt,{justifyContent:"flex-end",width:"100%"},Ze.createElement(kt,{dimColor:!0},"Crafted by Carlos Cochero \u2022 2025"))}function ye(){let{containers:t}=Ie(),e=Me(t);return e.creatingContainer?x.createElement(Ce,{step:e.creationStep,imageName:e.imageNameInput,containerName:e.containerNameInput,portInput:e.portInput,envInput:e.envInput,message:e.message,messageColor:e.messageColor}):x.createElement(x.Fragment,null,x.createElement(Lt,{flexDirection:"column",borderStyle:"round",borderColor:"cyan",padding:1},x.createElement(de,{count:t.length}),x.createElement(jt,null," "),x.createElement(me,{containers:t,selected:e.selected}),x.createElement(Dt,null),x.createElement(fe,{message:e.message,color:e.messageColor}),x.createElement(he,null),x.createElement(Te,null)),e.showLogs&&x.createElement(xe,{logs:e.logs,onExit:e.exitLogs,container:t[e.selected]}))}$t(Rt.createElement(ye,null));
8
+ //# sourceMappingURL=cdd.bundle.js.map
@@ -0,0 +1,48 @@
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import { PromptField, PromptMessage } from "./PromptField.jsx";
4
+ export default function ContainerCreationPrompt(props) {
5
+ var step = props.step,
6
+ imageName = props.imageName,
7
+ containerName = props.containerName,
8
+ portInput = props.portInput,
9
+ envInput = props.envInput,
10
+ message = props.message,
11
+ messageColor = props.messageColor;
12
+ var prompts = [{
13
+ label: "Name of the image to create (e.g., nginx:latest):",
14
+ value: imageName,
15
+ required: true
16
+ }, {
17
+ label: "Name of the container (optional):",
18
+ value: containerName,
19
+ required: false
20
+ }, {
21
+ label: "Ports (optional, format 8080:80,443:443):",
22
+ value: portInput,
23
+ required: false
24
+ }, {
25
+ label: "Environment variables (optional, format VAR1=val1,VAR2=val2):",
26
+ value: envInput,
27
+ required: false
28
+ }];
29
+ var _ref = prompts[step] || {},
30
+ label = _ref.label,
31
+ value = _ref.value,
32
+ required = _ref.required;
33
+ return /*#__PURE__*/React.createElement(Box, {
34
+ flexDirection: "column",
35
+ borderStyle: "round",
36
+ borderColor: "yellow",
37
+ padding: 1
38
+ }, /*#__PURE__*/React.createElement(PromptField, {
39
+ label: label,
40
+ value: value,
41
+ required: required
42
+ }), /*#__PURE__*/React.createElement(PromptMessage, {
43
+ message: message,
44
+ color: messageColor
45
+ }), /*#__PURE__*/React.createElement(Text, {
46
+ dimColor: true
47
+ }, "Press Enter to continue, Escape to cancel"));
48
+ }