cdd-cli 3.0.1 → 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.
- package/.github/workflows/ci.yml +29 -0
- package/CHANGELOG.md +27 -0
- package/CODE_OF_CONDUCT.md +12 -0
- package/CONTRIBUTING.md +22 -0
- package/README.md +69 -168
- package/SECURITY.md +5 -0
- package/babel.config.cjs +6 -0
- package/dist/App.js +38 -24
- package/dist/cdd.bundle.js +8 -0
- package/dist/components/ContainerCreationPrompt.js +48 -0
- package/dist/components/ContainerCreator.js +81 -0
- package/dist/components/ContainerList.js +24 -4
- package/dist/components/ContainerRow.js +66 -13
- package/dist/components/ContainerSection.js +14 -0
- package/dist/components/Footer.js +10 -0
- package/dist/components/PromptField.js +20 -0
- package/dist/components/UsageMenu.js +8 -0
- package/dist/helpers/actionHelpers.js +0 -1
- package/dist/helpers/dockerActions.js +13 -0
- package/dist/helpers/dockerService/dockerService.js +5 -0
- package/dist/helpers/dockerService/serviceComponents/containerActions.js +163 -0
- package/dist/helpers/dockerService/serviceComponents/containerList.js +57 -0
- package/dist/helpers/dockerService/serviceComponents/containerLogs.js +24 -0
- package/dist/helpers/dockerService/serviceComponents/containerStats.js +50 -0
- package/dist/helpers/dockerService/serviceComponents/imageUtils.js +52 -0
- package/dist/helpers/dockerService.js +111 -0
- package/dist/helpers/validationHelpers.js +26 -0
- package/dist/hooks/creation/useContainerActions.js +171 -0
- package/dist/hooks/creation/useContainerCreation.js +141 -0
- package/dist/hooks/creation/useLogsViewer.js +62 -0
- package/dist/hooks/useContainers.js +11 -1
- package/dist/hooks/useControls.js +298 -78
- package/dist/hooks/useLogsStream.js +1 -1
- package/dist/index.js +11 -0
- package/esbuild.config.cjs +11 -0
- package/jest.config.cjs +6 -0
- package/package.json +10 -6
- package/src/App.jsx +32 -26
- package/src/components/ContainerCreationPrompt.jsx +37 -0
- package/src/components/ContainerList.jsx +10 -6
- package/src/components/ContainerRow.jsx +36 -19
- package/src/components/ContainerSection.jsx +10 -0
- package/src/components/Footer.jsx +10 -0
- package/src/components/PromptField.jsx +18 -0
- package/src/components/UsageMenu.jsx +17 -0
- package/src/helpers/actionHelpers.js +0 -1
- package/src/helpers/dockerService/dockerService.js +3 -0
- package/src/helpers/dockerService/serviceComponents/containerActions.js +52 -0
- package/src/helpers/dockerService/serviceComponents/containerList.js +26 -0
- package/src/helpers/dockerService/serviceComponents/containerLogs.js +19 -0
- package/src/helpers/dockerService/serviceComponents/containerStats.js +34 -0
- package/src/helpers/dockerService/serviceComponents/imageUtils.js +21 -0
- package/src/helpers/validationHelpers.js +16 -0
- package/src/hooks/creation/useContainerActions.js +68 -0
- package/src/hooks/creation/useContainerCreation.js +104 -0
- package/src/hooks/creation/useLogsViewer.js +50 -0
- package/src/hooks/useContainers.js +1 -1
- package/src/hooks/useControls.js +176 -55
- package/src/hooks/useLogsStream.js +1 -1
- package/test/validationHelpers.test.js +28 -0
- package/PLAN_KEYBINDINGS_Y_REALTIME.md +0 -260
- package/docs/en/README.md +0 -167
- package/src/components/StatsViewer.jsx +0 -0
- package/src/helpers/dockerActions.js +0 -52
- package/src/helpers/dockerService.js +0 -100
package/docs/en/README.md
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# README (ENGLISH)
|
|
2
|
-
*Generated: 2025-10-13*
|
|
3
|
-
|
|
4
|
-
## Table of Contents
|
|
5
|
-
- [Project Scope](#project-scope)
|
|
6
|
-
- [Objectives & Roadmap](#objectives--roadmap)
|
|
7
|
-
- [Requirements](#requirements)
|
|
8
|
-
- [Installation](#installation)
|
|
9
|
-
- [Quick Start](#quick-start)
|
|
10
|
-
- [Use Cases](#use-cases)
|
|
11
|
-
- [Technical Documentation](#technical-documentation)
|
|
12
|
-
- [API Reference](#api-reference)
|
|
13
|
-
- [License](#license)
|
|
14
|
-
- [Contributing](#contributing)
|
|
15
|
-
- [Code of Conduct](#code-of-conduct)
|
|
16
|
-
- [Changelog](#changelog)
|
|
17
|
-
- [FAQ](#faq)
|
|
18
|
-
- [Publishing & Maintenance](#publishing--maintenance)
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Project Scope
|
|
23
|
-
This project is a cross-platform CLI tool for managing Docker containers with real-time log streaming and keyboard shortcuts. It is designed for developers and DevOps engineers who need fast, scriptable, and interactive container management from the terminal.
|
|
24
|
-
|
|
25
|
-
**What it does:**
|
|
26
|
-
- Lists, starts, stops, and removes Docker containers.
|
|
27
|
-
- Streams logs in real time.
|
|
28
|
-
- Provides keyboard shortcuts for common actions.
|
|
29
|
-
- Offers feedback and stats in the terminal.
|
|
30
|
-
|
|
31
|
-
**What it does NOT do:**
|
|
32
|
-
- Does not replace Docker Compose or advanced orchestration tools.
|
|
33
|
-
- Does not manage images or networks directly.
|
|
34
|
-
- No GUI; terminal only.
|
|
35
|
-
|
|
36
|
-
## Objectives & Roadmap
|
|
37
|
-
**Short-term (3 months):**
|
|
38
|
-
- Polish CLI UX and error handling.
|
|
39
|
-
- Add more keyboard shortcuts.
|
|
40
|
-
- Improve documentation and add more use cases.
|
|
41
|
-
|
|
42
|
-
**Medium-term (6 months):**
|
|
43
|
-
- Add plugin system for custom actions.
|
|
44
|
-
- Support for container stats export (JSON/CSV).
|
|
45
|
-
- Integration with CI/CD pipelines.
|
|
46
|
-
|
|
47
|
-
**Known limitations:**
|
|
48
|
-
- Requires Docker daemon running locally.
|
|
49
|
-
- Only supports local containers (no remote).
|
|
50
|
-
- Limited to Node.js LTS versions.
|
|
51
|
-
|
|
52
|
-
## Requirements
|
|
53
|
-
| Requirement | Minimum | Recommended |
|
|
54
|
-
|--------------------|----------------|-----------------|
|
|
55
|
-
| Node.js | 16.x | 18.x+ |
|
|
56
|
-
| npm | 7.x | 8.x+ |
|
|
57
|
-
| OS | Linux, macOS, Windows | Linux, macOS |
|
|
58
|
-
| Docker | 20.x | Latest stable |
|
|
59
|
-
| Permissions | Docker group or sudo | Docker group |
|
|
60
|
-
|
|
61
|
-
**Development:**
|
|
62
|
-
- ESLint, Prettier
|
|
63
|
-
- Jest or Mocha for tests
|
|
64
|
-
- GitHub Actions for CI
|
|
65
|
-
|
|
66
|
-
**Production:**
|
|
67
|
-
- Only Node.js and Docker required
|
|
68
|
-
|
|
69
|
-
## Installation
|
|
70
|
-
### Global install
|
|
71
|
-
```bash
|
|
72
|
-
npm install -g cdd-cli
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Update
|
|
76
|
-
```bash
|
|
77
|
-
npm update -g cdd-cli
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Uninstall
|
|
81
|
-
```bash
|
|
82
|
-
npm uninstall -g cdd-cli
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Check version
|
|
86
|
-
```bash
|
|
87
|
-
cdd -v
|
|
88
|
-
cdd --version
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
#### Notes
|
|
92
|
-
- On Linux/macOS, you may need `sudo` for global install.
|
|
93
|
-
- Ensure your global npm bin is in your PATH.
|
|
94
|
-
- On Windows, use an Administrator terminal if needed.
|
|
95
|
-
|
|
96
|
-
## Quick Start
|
|
97
|
-
```bash
|
|
98
|
-
cdd list
|
|
99
|
-
cdd logs <container>
|
|
100
|
-
cdd start <container>
|
|
101
|
-
cdd stop <container>
|
|
102
|
-
cdd remove <container>
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Use Cases
|
|
106
|
-
1. **List all containers**
|
|
107
|
-
- `cdd list`
|
|
108
|
-
- *Shows all containers with status.*
|
|
109
|
-
2. **Start a container**
|
|
110
|
-
- `cdd start my_container`
|
|
111
|
-
- *Starts the specified container.*
|
|
112
|
-
3. **Stop a container**
|
|
113
|
-
- `cdd stop my_container`
|
|
114
|
-
- *Stops the specified container.*
|
|
115
|
-
4. **Stream logs in real time**
|
|
116
|
-
- `cdd logs my_container`
|
|
117
|
-
- *Shows live logs with color highlighting.*
|
|
118
|
-
5. **Remove a container**
|
|
119
|
-
- `cdd remove my_container`
|
|
120
|
-
- *Deletes the container after confirmation.*
|
|
121
|
-
6. **Use keyboard shortcuts**
|
|
122
|
-
- While viewing logs, press `q` to quit, `r` to restart, etc.
|
|
123
|
-
|
|
124
|
-
## Technical Documentation
|
|
125
|
-
See inline JSDoc comments in source files. Example:
|
|
126
|
-
```js
|
|
127
|
-
/**
|
|
128
|
-
* Start a Docker container by name.
|
|
129
|
-
* @param {string} name - Container name
|
|
130
|
-
* @returns {Promise<boolean>} True if started
|
|
131
|
-
* @throws {Error} If Docker is not running
|
|
132
|
-
* @example
|
|
133
|
-
* await startContainer('my_container');
|
|
134
|
-
*/
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## API Reference
|
|
138
|
-
See [API Reference](./api.md) for all exported functions and CLI commands.
|
|
139
|
-
|
|
140
|
-
## License
|
|
141
|
-
MIT License. See [LICENSE](../../LICENSE).
|
|
142
|
-
|
|
143
|
-
## Contributing
|
|
144
|
-
See [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
|
145
|
-
|
|
146
|
-
## Code of Conduct
|
|
147
|
-
See [CODE_OF_CONDUCT.md](../../CODE_OF_CONDUCT.md).
|
|
148
|
-
|
|
149
|
-
## Changelog
|
|
150
|
-
See [CHANGELOG.md](../../CHANGELOG.md).
|
|
151
|
-
|
|
152
|
-
## FAQ
|
|
153
|
-
- **Does it work with Docker Desktop?**
|
|
154
|
-
- Yes, as long as Docker CLI is available.
|
|
155
|
-
- **Can I use it in CI?**
|
|
156
|
-
- Yes, see examples below.
|
|
157
|
-
- **How do I add my own commands?**
|
|
158
|
-
- Plugin system coming soon.
|
|
159
|
-
|
|
160
|
-
## Publishing & Maintenance
|
|
161
|
-
To publish to npm:
|
|
162
|
-
```bash
|
|
163
|
-
npm login
|
|
164
|
-
npm publish --access public
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Keep documentation updated with every release. See CONTRIBUTING.md for details.
|
|
File without changes
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Run a Docker action by name (start, stop, remove).
|
|
3
|
-
* Ejecuta una acción Docker por nombre (start, stop, remove).
|
|
4
|
-
*
|
|
5
|
-
* @param {string} action - Action to perform / Acción a realizar
|
|
6
|
-
* @param {string} container - Container name / Nombre del contenedor
|
|
7
|
-
* @returns {Promise<boolean>} True if successful / True si es exitoso
|
|
8
|
-
* @throws {Error} If Docker is not running / Si Docker no está corriendo
|
|
9
|
-
* @example
|
|
10
|
-
* // EN: Start a container
|
|
11
|
-
* // ES: Iniciar un contenedor
|
|
12
|
-
* await runDockerAction('start', 'my_container');
|
|
13
|
-
*/
|
|
14
|
-
import { spawn } from "child_process";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Ejecuta una acción de Docker sobre un contenedor y maneja feedback visual.
|
|
18
|
-
* @param {Object} params
|
|
19
|
-
* @param {Array} params.containers - Lista de contenedores.
|
|
20
|
-
* @param {number} params.selected - Índice del contenedor seleccionado.
|
|
21
|
-
* @param {string} params.action - Acción docker (start, stop, restart).
|
|
22
|
-
* @param {string} params.actionLabel - Texto para feedback (Starting, Stopping, etc).
|
|
23
|
-
* @param {Function} params.setMessage - Setter de mensaje visual.
|
|
24
|
-
* @param {Function} params.setMessageColor - Setter de color del mensaje.
|
|
25
|
-
*/
|
|
26
|
-
export function handleDockerAction({ containers, selected, action, actionLabel, setMessage, setMessageColor }) {
|
|
27
|
-
if (containers[selected]) {
|
|
28
|
-
const c = containers[selected];
|
|
29
|
-
const id = c.id || c.name;
|
|
30
|
-
// Validación de estado
|
|
31
|
-
if (action === "start" && (c.state === "running" || c.status === "running")) {
|
|
32
|
-
setMessage("Container is already running.");
|
|
33
|
-
setMessageColor("red");
|
|
34
|
-
setTimeout(() => setMessage(""), 2000);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
if (action === "stop" && (c.state === "exited" || c.status === "exited" || c.state === "stopped" || c.status === "stopped")) {
|
|
38
|
-
setMessage("Container is already stopped.");
|
|
39
|
-
setMessageColor("red");
|
|
40
|
-
setTimeout(() => setMessage(""), 2000);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
setMessage(`${actionLabel} container...`);
|
|
44
|
-
setMessageColor("green");
|
|
45
|
-
const child = spawn("docker", [action, id]);
|
|
46
|
-
child.on("close", () => {
|
|
47
|
-
setMessage(`${actionLabel} container...`);
|
|
48
|
-
setMessageColor("green");
|
|
49
|
-
setTimeout(() => setMessage(""), 3000);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility to interact with Docker CLI.
|
|
3
|
-
* Utilidad para interactuar con el CLI de Docker.
|
|
4
|
-
*
|
|
5
|
-
* @param {string} cmd - Docker command / Comando Docker
|
|
6
|
-
* @returns {Promise<string>} Output from Docker / Salida de Docker
|
|
7
|
-
* @throws {Error} If command fails / Si el comando falla
|
|
8
|
-
* @example
|
|
9
|
-
* // EN: Run a Docker command
|
|
10
|
-
* // ES: Ejecutar un comando Docker
|
|
11
|
-
* await dockerService('ps -a');
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import Docker from "dockerode";
|
|
15
|
-
const docker = new Docker({ socketPath: "/var/run/docker.sock" });
|
|
16
|
-
|
|
17
|
-
export function getLogsStream(containerId, onData, onEnd, onError) {
|
|
18
|
-
const container = docker.getContainer(containerId);
|
|
19
|
-
container.logs({
|
|
20
|
-
follow: true,
|
|
21
|
-
stdout: true,
|
|
22
|
-
stderr: true,
|
|
23
|
-
tail: 100
|
|
24
|
-
}, (err, stream) => {
|
|
25
|
-
if (err) {
|
|
26
|
-
onError?.(err);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
stream.on('data', chunk => onData?.(chunk.toString()));
|
|
30
|
-
stream.on('end', () => onEnd?.());
|
|
31
|
-
stream.on('error', err => onError?.(err));
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function startContainer(containerId) {
|
|
36
|
-
const container = docker.getContainer(containerId);
|
|
37
|
-
await container.start();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function stopContainer(containerId) {
|
|
41
|
-
const container = docker.getContainer(containerId);
|
|
42
|
-
await container.stop();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function restartContainer(containerId) {
|
|
46
|
-
const container = docker.getContainer(containerId);
|
|
47
|
-
await container.restart();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export async function getContainers() {
|
|
51
|
-
const containers = await docker.listContainers({ all: true });
|
|
52
|
-
return containers.map((container) => ({
|
|
53
|
-
id: container.Id,
|
|
54
|
-
name: container.Names[0].replace("/", ""),
|
|
55
|
-
image: container.Image,
|
|
56
|
-
state: container.State,
|
|
57
|
-
status: container.Status,
|
|
58
|
-
ports:
|
|
59
|
-
[
|
|
60
|
-
...new Set(
|
|
61
|
-
container.Ports.filter((port) => port.PublicPort).map(
|
|
62
|
-
(port) => `${port.PublicPort}:${port.PrivatePort}`
|
|
63
|
-
)
|
|
64
|
-
),
|
|
65
|
-
]
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export async function getStats(containerId) {
|
|
70
|
-
const container = docker.getContainer(containerId);
|
|
71
|
-
const stream = await container.stats({ stream: false });
|
|
72
|
-
|
|
73
|
-
const cpuDelta =
|
|
74
|
-
stream.cpu_stats.cpu_usage.total_usage -
|
|
75
|
-
stream.precpu_stats.cpu_usage.total_usage;
|
|
76
|
-
const systemDelta =
|
|
77
|
-
stream.cpu_stats.system_cpu_usage - stream.precpu_stats.system_cpu_usage;
|
|
78
|
-
const cpuPercent = systemDelta > 0 ? (cpuDelta / systemDelta) * 100 : 0;
|
|
79
|
-
|
|
80
|
-
const memUsage = stream.memory_stats.usage || 0;
|
|
81
|
-
const memLimit = stream.memory_stats.limit || 1;
|
|
82
|
-
const memPercent = (memUsage / memLimit) * 100;
|
|
83
|
-
|
|
84
|
-
const rx = stream.networks
|
|
85
|
-
? Object.values(stream.networks)
|
|
86
|
-
.map((n) => n.rx_bytes)
|
|
87
|
-
.reduce((a, b) => a + b, 0)
|
|
88
|
-
: 0;
|
|
89
|
-
const tx = stream.networks
|
|
90
|
-
? Object.values(stream.networks)
|
|
91
|
-
.map((n) => n.tx_bytes)
|
|
92
|
-
.reduce((a, b) => a + b, 0)
|
|
93
|
-
: 0;
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
cpuPercent: cpuPercent.toFixed(1),
|
|
97
|
-
memPercent: memPercent.toFixed(1),
|
|
98
|
-
netIO: { rx, tx },
|
|
99
|
-
};
|
|
100
|
-
}
|