@mytinyapps/dockerino 0.5.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrea
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # 🐳 dockerino
2
+
3
+ A **Terminal User Interface (TUI)** for Docker. Manage containers, images, and volumes from a beautiful interactive terminal dashboard — no GUI needed.
4
+
5
+ ![License](https://img.shields.io/github/license/andrea/dockerino)
6
+ ![npm](https://img.shields.io/npm/v/dockerino)
7
+ ![Node](https://img.shields.io/node/v/dockerino)
8
+
9
+ ## Features
10
+
11
+ - **Containers** — Start, stop, restart, remove, inspect, view logs, open shell
12
+ - **Images** — List, delete, inspect details
13
+ - **Volumes** — List, delete, inspect with usage info
14
+ - **Docker Compose** — Automatic grouping by Compose project
15
+ - **Adaptive layout** — Wide terminals show inline stats columns; narrow terminals show a detail panel
16
+ - **Live stats** — CPU, memory, network I/O updated every 5 seconds
17
+ - **Log viewer** — Streaming logs with real-time text filtering
18
+ - **Interactive shell** — Open a shell inside any running container
19
+ - **Tab navigation** — Switch between Containers, Images, and Volumes with `Alt+C/I/V`
20
+
21
+ ## Quick start
22
+
23
+ Run directly without installing:
24
+
25
+ ```bash
26
+ npx dockerino
27
+ ```
28
+
29
+ ## Installation
30
+
31
+ Or install globally:
32
+
33
+ ```bash
34
+ npm install -g dockerino
35
+ ```
36
+
37
+ ## Requirements
38
+
39
+ - **Node.js** ≥ 18
40
+ - **Docker CLI** (`docker`) available in your `PATH`
41
+ - Docker daemon running
42
+
43
+ ## Usage
44
+
45
+ ```bash
46
+ dockerino
47
+ ```
48
+
49
+ ### Keyboard shortcuts
50
+
51
+ #### Containers tab
52
+
53
+ | Key | Action |
54
+ | ------- | --------------------------- |
55
+ | `↑` `↓` | Navigate |
56
+ | `s` | Start container |
57
+ | `S` | Stop container |
58
+ | `r` | Restart container |
59
+ | `Del` | Remove container (exited) |
60
+ | `d` | Show container details |
61
+ | `l` | Open log viewer |
62
+ | `h` | Open shell in container |
63
+ | `R` | Refresh |
64
+
65
+ #### Images / Volumes tabs
66
+
67
+ | Key | Action |
68
+ | ------- | -------------- |
69
+ | `↑` `↓` | Navigate |
70
+ | `Del` | Delete |
71
+ | `d` | Show details |
72
+ | `R` | Refresh |
73
+
74
+ #### Global
75
+
76
+ | Key | Action |
77
+ | ---------------- | -------------------- |
78
+ | `Alt+C` | Containers tab |
79
+ | `Alt+I` | Images tab |
80
+ | `Alt+V` | Volumes tab |
81
+ | `Alt+1/2/3` | Switch tab by number |
82
+ | `q` / `Esc` | Quit |
83
+
84
+ ## Development
85
+
86
+ ```bash
87
+ git clone https://github.com/andrea/dockerino.git
88
+ cd dockerino
89
+ npm install
90
+ npm run build
91
+ npm start
92
+ ```
93
+
94
+ ### Scripts
95
+
96
+ | Command | Description |
97
+ | ---------------- | ---------------------------- |
98
+ | `npm run build` | Compile TypeScript |
99
+ | `npm run dev` | Watch mode |
100
+ | `npm start` | Run dockerino |
101
+ | `npm run lint` | Lint with ESLint |
102
+
103
+ ## Architecture
104
+
105
+ ```
106
+ src/
107
+ index.ts # Entry point, bootstrap TUI
108
+ ui/ # Blessed components (dashboard, layout)
109
+ docker/ # Docker CLI interaction
110
+ commands.ts # Async wrappers around docker commands
111
+ parser.ts # Output parsing (JSON/text)
112
+ types.ts # TypeScript interfaces
113
+ bin/
114
+ dockerino.ts # CLI entry point
115
+ ```
116
+
117
+ All Docker interaction happens via `child_process.execFile` / `spawn` with argument arrays (no shell interpolation), communicating with the local `docker` CLI. No Docker Engine API or HTTP calls.
118
+
119
+ ## Contributing
120
+
121
+ Contributions are welcome! Feel free to open issues and pull requests.
122
+
123
+ 1. Fork the repository
124
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
125
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
126
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
127
+ 5. Open a Pull Request
128
+
129
+ ## License
130
+
131
+ This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import '../src/index.js';
3
+ //# sourceMappingURL=dockerino.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dockerino.d.ts","sourceRoot":"","sources":["../../bin/dockerino.ts"],"names":[],"mappings":";AACA,OAAO,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import '../src/index.js';
3
+ //# sourceMappingURL=dockerino.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dockerino.js","sourceRoot":"","sources":["../../bin/dockerino.ts"],"names":[],"mappings":";AACA,OAAO,iBAAiB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { Container, ContainerStats, Image, Volume } from '../types.js';
2
+ export declare function listContainers(all?: boolean): Promise<Container[]>;
3
+ export declare function getContainerStats(): Promise<ContainerStats[]>;
4
+ export declare function startContainer(id: string): Promise<void>;
5
+ export declare function stopContainer(id: string): Promise<void>;
6
+ export declare function restartContainer(id: string): Promise<void>;
7
+ export declare function removeContainer(id: string, force?: boolean): Promise<void>;
8
+ /** Check which shell is available in a container: tries bash first, falls back to sh */
9
+ export declare function detectShell(containerId: string): Promise<string>;
10
+ export declare function listImages(): Promise<Image[]>;
11
+ export declare function removeImage(id: string, force?: boolean): Promise<void>;
12
+ export interface ContainerInspect {
13
+ mounts: {
14
+ type: string;
15
+ source: string;
16
+ destination: string;
17
+ mode: string;
18
+ rw: boolean;
19
+ }[];
20
+ env: string[];
21
+ }
22
+ export declare function inspectContainer(id: string): Promise<ContainerInspect>;
23
+ export declare function listVolumes(): Promise<Volume[]>;
24
+ export declare function removeVolume(name: string, force?: boolean): Promise<void>;
25
+ export interface VolumeInspect {
26
+ createdAt: string;
27
+ driver: string;
28
+ mountpoint: string;
29
+ scope: string;
30
+ labels: Record<string, string>;
31
+ options: Record<string, string>;
32
+ usedBy: string[];
33
+ }
34
+ export declare function inspectVolume(name: string): Promise<VolumeInspect>;
35
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../src/docker/commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAcvE,wBAAsB,cAAc,CAAC,GAAG,UAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA6BrE;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAiBnE;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9E;AAED,wFAAwF;AACxF,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOtE;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAanD;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAI1E;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAC3F,GAAG,EAAE,MAAM,EAAE,CAAC;CACf;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAY5E;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAYrD;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7E;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAuBxE"}
@@ -0,0 +1,166 @@
1
+ import { execFile } from 'node:child_process';
2
+ function exec(args) {
3
+ return new Promise((resolve, reject) => {
4
+ execFile('docker', args, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
5
+ if (err) {
6
+ reject(new Error(stderr.trim() || err.message));
7
+ return;
8
+ }
9
+ resolve(stdout);
10
+ });
11
+ });
12
+ }
13
+ export async function listContainers(all = true) {
14
+ const args = ['ps', '--format', 'json', '--no-trunc'];
15
+ if (all)
16
+ args.push('-a');
17
+ const output = await exec(args);
18
+ if (!output.trim())
19
+ return [];
20
+ // docker ps --format json outputs one JSON object per line
21
+ return output.trim().split('\n').map((line) => {
22
+ const raw = JSON.parse(line);
23
+ // Parse compose labels from the Labels string (key=value,key=value)
24
+ const labels = {};
25
+ if (raw.Labels) {
26
+ for (const pair of String(raw.Labels).split(',')) {
27
+ const eq = pair.indexOf('=');
28
+ if (eq > 0)
29
+ labels[pair.slice(0, eq)] = pair.slice(eq + 1);
30
+ }
31
+ }
32
+ return {
33
+ id: raw.ID,
34
+ name: raw.Names,
35
+ image: raw.Image,
36
+ status: raw.Status,
37
+ state: raw.State?.toLowerCase() ?? 'created',
38
+ ports: raw.Ports || '',
39
+ created: raw.CreatedAt || raw.RunningFor || '',
40
+ size: raw.Size,
41
+ composeProject: labels['com.docker.compose.project'],
42
+ composeService: labels['com.docker.compose.service'],
43
+ };
44
+ });
45
+ }
46
+ export async function getContainerStats() {
47
+ const args = ['stats', '--no-stream', '--format', 'json'];
48
+ const output = await exec(args);
49
+ if (!output.trim())
50
+ return [];
51
+ return output.trim().split('\n').map((line) => {
52
+ const raw = JSON.parse(line);
53
+ return {
54
+ id: raw.ID,
55
+ name: raw.Name,
56
+ cpuPercent: raw.CPUPerc,
57
+ memUsage: raw.MemUsage,
58
+ memPercent: raw.MemPerc,
59
+ netIO: raw.NetIO,
60
+ blockIO: raw.BlockIO,
61
+ pids: raw.PIDs,
62
+ };
63
+ });
64
+ }
65
+ export async function startContainer(id) {
66
+ await exec(['start', id]);
67
+ }
68
+ export async function stopContainer(id) {
69
+ await exec(['stop', id]);
70
+ }
71
+ export async function restartContainer(id) {
72
+ await exec(['restart', id]);
73
+ }
74
+ export async function removeContainer(id, force = false) {
75
+ const args = ['rm', id];
76
+ if (force)
77
+ args.push('-f');
78
+ await exec(args);
79
+ }
80
+ /** Check which shell is available in a container: tries bash first, falls back to sh */
81
+ export async function detectShell(containerId) {
82
+ try {
83
+ await exec(['exec', containerId, 'test', '-x', '/bin/bash']);
84
+ return '/bin/bash';
85
+ }
86
+ catch {
87
+ return '/bin/sh';
88
+ }
89
+ }
90
+ export async function listImages() {
91
+ const output = await exec(['images', '--format', 'json']);
92
+ if (!output.trim())
93
+ return [];
94
+ return output.trim().split('\n').map((line) => {
95
+ const raw = JSON.parse(line);
96
+ return {
97
+ id: raw.ID,
98
+ repository: raw.Repository,
99
+ tag: raw.Tag,
100
+ size: raw.Size,
101
+ created: raw.CreatedSince || raw.CreatedAt || '',
102
+ };
103
+ });
104
+ }
105
+ export async function removeImage(id, force = false) {
106
+ const args = ['rmi', id];
107
+ if (force)
108
+ args.push('-f');
109
+ await exec(args);
110
+ }
111
+ export async function inspectContainer(id) {
112
+ const output = await exec(['inspect', '--format', '{{json .}}', id]);
113
+ const raw = JSON.parse(output.trim());
114
+ const mounts = (raw.Mounts ?? []).map((m) => ({
115
+ type: String(m.Type ?? ''),
116
+ source: String(m.Source ?? ''),
117
+ destination: String(m.Destination ?? ''),
118
+ mode: String(m.Mode ?? ''),
119
+ rw: Boolean(m.RW),
120
+ }));
121
+ const env = raw.Config?.Env ?? [];
122
+ return { mounts, env };
123
+ }
124
+ export async function listVolumes() {
125
+ const output = await exec(['volume', 'ls', '--format', 'json']);
126
+ if (!output.trim())
127
+ return [];
128
+ return output.trim().split('\n').map((line) => {
129
+ const raw = JSON.parse(line);
130
+ return {
131
+ name: raw.Name,
132
+ driver: raw.Driver,
133
+ mountpoint: raw.Mountpoint,
134
+ scope: raw.Scope ?? 'local',
135
+ };
136
+ });
137
+ }
138
+ export async function removeVolume(name, force = false) {
139
+ const args = ['volume', 'rm', name];
140
+ if (force)
141
+ args.push('-f');
142
+ await exec(args);
143
+ }
144
+ export async function inspectVolume(name) {
145
+ const output = await exec(['volume', 'inspect', '--format', '{{json .}}', name]);
146
+ const raw = JSON.parse(output.trim());
147
+ const labels = raw.Labels ?? {};
148
+ const options = raw.Options ?? {};
149
+ // Find containers using this volume
150
+ let usedBy = [];
151
+ try {
152
+ const psOut = await exec(['ps', '-a', '--filter', `volume=${name}`, '--format', '{{.Names}}']);
153
+ usedBy = psOut.trim().split('\n').filter(Boolean);
154
+ }
155
+ catch { /* no containers */ }
156
+ return {
157
+ createdAt: raw.CreatedAt ?? '',
158
+ driver: raw.Driver ?? '',
159
+ mountpoint: raw.Mountpoint ?? '',
160
+ scope: raw.Scope ?? 'local',
161
+ labels,
162
+ options,
163
+ usedBy,
164
+ };
165
+ }
166
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/docker/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { createDashboard } from './ui/dashboard.js';
2
+ createDashboard();
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,eAAe,EAAE,CAAC"}
@@ -0,0 +1,36 @@
1
+ export interface Container {
2
+ id: string;
3
+ name: string;
4
+ image: string;
5
+ status: string;
6
+ state: 'running' | 'exited' | 'paused' | 'restarting' | 'dead' | 'created';
7
+ ports: string;
8
+ created: string;
9
+ size?: string;
10
+ composeProject?: string;
11
+ composeService?: string;
12
+ }
13
+ export interface ContainerStats {
14
+ id: string;
15
+ name: string;
16
+ cpuPercent: string;
17
+ memUsage: string;
18
+ memPercent: string;
19
+ netIO: string;
20
+ blockIO: string;
21
+ pids: string;
22
+ }
23
+ export interface Image {
24
+ id: string;
25
+ repository: string;
26
+ tag: string;
27
+ size: string;
28
+ created: string;
29
+ }
30
+ export interface Volume {
31
+ name: string;
32
+ driver: string;
33
+ mountpoint: string;
34
+ scope: string;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import blessed from 'neo-blessed';
2
+ /**
3
+ * Main dashboard — adaptive table layout.
4
+ *
5
+ * Wide (≥120 cols): stats as columns
6
+ * ┌─ Containers ──────────────────────────────────────────────────────┐
7
+ * │ STATE NAME IMAGE STATUS CPU MEM │
8
+ * │ ▼ my-project │
9
+ * │ ├─ web nginx:latest Up 2h 1.2% 45M │
10
+ * │ └─ db postgres:16 Up 2h 3.1% 120M │
11
+ * │ standalone alpine:3.19 Exited │
12
+ * ├───────────────────────────────────────────────────────────────────┤
13
+ * │ ↑↓ Navigate s Start S Stop r Restart d Remove R Refresh │
14
+ * └───────────────────────────────────────────────────────────────────┘
15
+ *
16
+ * Narrow (<120 cols): detail panel at the bottom
17
+ * ┌─ Containers ──────────────────────────────┐
18
+ * │ STATE NAME IMAGE STATUS │
19
+ * ├─ Detail ──────────────────────────────────┤
20
+ * │ CPU: 1.2% MEM: 45Mi (12%) NET: 1.2kB │
21
+ * ├───────────────────────────────────────────┤
22
+ * │ ↑↓ Navigate s Start ... │
23
+ * └───────────────────────────────────────────┘
24
+ *
25
+ * Keys: ↑↓/j/k navigate, s start, S stop, r restart,
26
+ * d remove (exited only), R refresh, q/Esc quit
27
+ */
28
+ export declare function createDashboard(): blessed.Widgets.Screen;
29
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/ui/dashboard.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,aAAa,CAAC;AAsClC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CA66BxD"}