cdd-cli 3.0.1 → 3.1.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 (68) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +30 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  3. package/.github/PULL_REQUEST_TEMPLATE/pull_request.md +14 -0
  4. package/.github/workflows/ci.yml +29 -0
  5. package/CHANGELOG.md +34 -0
  6. package/CODE_OF_CONDUCT.md +12 -0
  7. package/CONTRIBUTING.md +22 -0
  8. package/README.md +83 -166
  9. package/SECURITY.md +5 -0
  10. package/babel.config.cjs +6 -0
  11. package/dist/App.js +38 -24
  12. package/dist/cdd.bundle.js +8 -0
  13. package/dist/components/ContainerCreationPrompt.js +48 -0
  14. package/dist/components/ContainerCreator.js +81 -0
  15. package/dist/components/ContainerList.js +24 -4
  16. package/dist/components/ContainerRow.js +66 -13
  17. package/dist/components/ContainerSection.js +14 -0
  18. package/dist/components/Footer.js +10 -0
  19. package/dist/components/PromptField.js +20 -0
  20. package/dist/components/UsageMenu.js +8 -0
  21. package/dist/helpers/actionHelpers.js +0 -1
  22. package/dist/helpers/dockerActions.js +13 -0
  23. package/dist/helpers/dockerService/dockerService.js +5 -0
  24. package/dist/helpers/dockerService/serviceComponents/containerActions.js +163 -0
  25. package/dist/helpers/dockerService/serviceComponents/containerList.js +57 -0
  26. package/dist/helpers/dockerService/serviceComponents/containerLogs.js +24 -0
  27. package/dist/helpers/dockerService/serviceComponents/containerStats.js +50 -0
  28. package/dist/helpers/dockerService/serviceComponents/imageUtils.js +52 -0
  29. package/dist/helpers/dockerService.js +111 -0
  30. package/dist/helpers/validationHelpers.js +26 -0
  31. package/dist/hooks/creation/useContainerActions.js +171 -0
  32. package/dist/hooks/creation/useContainerCreation.js +141 -0
  33. package/dist/hooks/creation/useLogsViewer.js +62 -0
  34. package/dist/hooks/useContainers.js +11 -1
  35. package/dist/hooks/useControls.js +298 -78
  36. package/dist/hooks/useLogsStream.js +1 -1
  37. package/dist/index.js +11 -0
  38. package/esbuild.config.cjs +11 -0
  39. package/jest.config.cjs +6 -0
  40. package/package.json +10 -6
  41. package/src/App.jsx +32 -26
  42. package/src/components/ContainerCreationPrompt.jsx +37 -0
  43. package/src/components/ContainerList.jsx +10 -6
  44. package/src/components/ContainerRow.jsx +36 -19
  45. package/src/components/ContainerSection.jsx +10 -0
  46. package/src/components/Footer.jsx +10 -0
  47. package/src/components/PromptField.jsx +18 -0
  48. package/src/components/UsageMenu.jsx +17 -0
  49. package/src/helpers/actionHelpers.js +0 -1
  50. package/src/helpers/dockerService/dockerService.js +3 -0
  51. package/src/helpers/dockerService/serviceComponents/containerActions.js +52 -0
  52. package/src/helpers/dockerService/serviceComponents/containerList.js +26 -0
  53. package/src/helpers/dockerService/serviceComponents/containerLogs.js +19 -0
  54. package/src/helpers/dockerService/serviceComponents/containerStats.js +34 -0
  55. package/src/helpers/dockerService/serviceComponents/imageUtils.js +21 -0
  56. package/src/helpers/validationHelpers.js +16 -0
  57. package/src/hooks/creation/useContainerActions.js +68 -0
  58. package/src/hooks/creation/useContainerCreation.js +104 -0
  59. package/src/hooks/creation/useLogsViewer.js +50 -0
  60. package/src/hooks/useContainers.js +1 -1
  61. package/src/hooks/useControls.js +176 -55
  62. package/src/hooks/useLogsStream.js +1 -1
  63. package/test/validationHelpers.test.js +28 -0
  64. package/PLAN_KEYBINDINGS_Y_REALTIME.md +0 -260
  65. package/docs/en/README.md +0 -167
  66. package/src/components/StatsViewer.jsx +0 -0
  67. package/src/helpers/dockerActions.js +0 -52
  68. package/src/helpers/dockerService.js +0 -100
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: bug
6
+ assignees: ''
7
+ ---
8
+
9
+ **Describe the bug**
10
+ A clear and concise description of what the bug is.
11
+
12
+ **To Reproduce**
13
+ Steps to reproduce the behavior:
14
+ 1. Go to '...'
15
+ 2. Run '...'
16
+ 3. See error
17
+
18
+ **Expected behavior**
19
+ A clear and concise description of what you expected to happen.
20
+
21
+ **Screenshots or logs**
22
+ If applicable, add screenshots or logs to help explain your problem.
23
+
24
+ **Environment (please complete the following information):**
25
+ - OS: (e.g. Ubuntu 22.04)
26
+ - Node version: (e.g. 18.x)
27
+ - cdd-cli version: (e.g. 3.1.0)
28
+
29
+ **Additional context**
30
+ Add any other context about the problem here.
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: enhancement
6
+ assignees: ''
7
+ ---
8
+
9
+ **Is your feature request related to a problem? Please describe.**
10
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11
+
12
+ **Describe the solution you'd like**
13
+ A clear and concise description of what you want to happen.
14
+
15
+ **Describe alternatives you've considered**
16
+ A clear and concise description of any alternative solutions or features you've considered.
17
+
18
+ **Additional context**
19
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,14 @@
1
+ <!-- Please replace the placeholders and remove this comment -->
2
+ ## Summary
3
+
4
+ What does this PR change and why?
5
+
6
+ ## Checklist
7
+
8
+ - [ ] I have read the contributing guidelines
9
+ - [ ] Tests added / updated
10
+ - [ ] Documentation updated
11
+
12
+ ## Related issues
13
+
14
+ Closes: # (issue)
@@ -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,34 @@
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
28
+
29
+ ## [3.1.1] - 2025-10-16
30
+
31
+ ### Fixed
32
+
33
+ - Minor docs typo fixes and README global install note added.
34
+
@@ -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/README.md CHANGED
@@ -1,205 +1,122 @@
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
+ ```
66
24
 
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
- ```
25
+ 2. Build and run locally:
74
26
 
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.
27
+ ```bash
28
+ npm run build
29
+ node dist/index.js
30
+ ```
31
+
32
+ 3. To test the CLI as a globally available command during development:
33
+
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
+ ## Install globally
57
+
58
+ To install the CLI globally so you can run `cdd` from any terminal, use:
59
+
60
+ ```bash
61
+ npm install -g cdd-cli
124
62
  ```
125
63
 
126
- [English version below]
64
+ After installing globally, run the CLI with:
65
+
66
+ ```bash
67
+ cdd
68
+ ```
127
69
 
128
70
  ---
129
71
 
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.
72
+ ## Development
132
73
 
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).
74
+ - Node.js >= 18 is recommended.
75
+ - To run the app from source during development:
138
76
 
139
- ## Instalación global
77
+ ```bash
78
+ npm install
79
+ npm run build
80
+ node dist/index.js
81
+ ```
140
82
 
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
- ```
83
+ If you change source files, re-run `npm run build` before running the CLI.
84
+
85
+ ---
150
86
 
151
- ## Uso
152
- - Al ejecutar `cdd`, verás una tabla interactiva con todos tus contenedores Docker.
153
- - Los contenedores en ejecución muestran estadísticas de CPU y memoria en tiempo real.
154
- - Puedes navegar usando las flechas ↑/↓ y controlar los contenedores con atajos de teclado.
155
- - Usa `Ctrl+C` o la tecla `Q` para salir.
87
+ ## Tests
156
88
 
157
- ### ⌨️ Atajos de teclado
89
+ We use Jest for unit tests. Run:
158
90
 
159
- - ↑ / ↓ : Navegar entre contenedores
160
- - I : Iniciar el contenedor seleccionado
161
- - P : Parar el contenedor seleccionado
162
- - L : Ver logs en tiempo real del contenedor seleccionado
163
- - Q : Salir del dashboard o de la vista de logs
91
+ ```bash
92
+ npm test
93
+ ```
164
94
 
165
- ## Funcionalidades principales
166
- - 🐳 Visualización clara y compacta de todos los contenedores.
167
- - 🔄 Refresco automático de datos.
168
- - 📊 Estadísticas de uso de recursos para contenedores activos.
169
- - 🎨 Interfaz visual con colores y emojis para estados.
170
- - 👤 Autor: Carlos Cochero (2025)
95
+ Tests are located in `test/` and cover utility helpers.
171
96
 
172
- ## Requisitos
173
- - Node.js >= 18
174
- - Docker instalado y corriendo (el CLI se conecta al socket local de Docker)
97
+ ---
175
98
 
176
- ## Troubleshooting
177
- - Si no ves contenedores, asegúrate de que Docker esté corriendo y tu usuario tenga permisos para acceder al socket Docker.
178
- - Si tienes problemas con la instalación global, prueba con `sudo` (Linux/macOS) o ejecuta la terminal como administrador (Windows).
99
+ ## Contributing
100
+
101
+ 1. Fork the repo and create a feature branch.
102
+ 2. Add tests for new behavior.
103
+ 3. Ensure `npm test` and `npm run build` pass.
104
+ 4. Open a Pull Request with a clear description.
179
105
 
180
106
  ---
181
107
 
182
- # 🐳 CDD-CLI — Docker Dashboard in your Terminal
108
+ ## Troubleshooting
183
109
 
184
- ## Description
185
- 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.
110
+ - If you don't see containers, ensure Docker is running and that your user has access to the Docker socket.
111
+ - If Docker permissions are required, run the CLI with `sudo` (Linux/macOS) or as Administrator (Windows).
112
+ - The project generates `dist/` — keep it out of version control (it's in .gitignore).
186
113
 
187
- - See all running and stopped containers.
188
- - Shows name, image, state, ports, and CPU/MEM stats.
189
- - Auto-refresh every 2 seconds.
190
- - Friendly, colorful, emoji-rich UI.
191
- - Works on Linux, macOS, and Windows (bash, cmd, PowerShell).
114
+ ---
192
115
 
193
- ## Global installation
116
+ ## License
117
+
118
+ This project is MIT/ISC licensed (see `LICENSE`).
194
119
 
195
- 1. Make sure you have Node.js (v18+) and Docker installed and running.
196
- 2. Install the CLI globally from npm:
197
- ```bash
198
- npm install -g cdd-cli
199
- ```
200
- 3. Run the dashboard from any terminal:
201
- ```bash
202
- cdd
203
120
  ```
204
121
 
205
122
  ## Usage
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
+ }