recomposable 1.0.2 → 1.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.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  A lightweight Docker Compose TUI manager with vim keybindings. Monitor service status, restart or rebuild containers, and tail logs — all from your terminal.
4
4
 
5
+ Eliminate switching between countless terminal tabs or windows to rebuild you docker compose containers.
6
+
5
7
  Zero dependencies. Pure Node.js.
6
8
 
7
9
  ![recomposable list view](screenshots/list-view.png)
@@ -36,16 +38,36 @@ recomposable
36
38
 
37
39
  - **Multi-file support** — manage services across multiple compose files, grouped by file
38
40
  - **Live status** — polls container state, health, build and restart times
41
+ - **CPU/Memory monitoring** — live CPU% and memory usage per container, with configurable color thresholds
42
+ - **Port mappings** — shows published ports for each service
39
43
  - **Log pattern scanning** — counts WRN/ERR (configurable) occurrences across all services
40
- - **Inline log panel** — tail logs for the selected service without leaving the list view
41
- - **Full log view** — scrollable full-screen log viewer with live auto-scroll
42
- - **Rebuild & restart** trigger `docker compose up -d --build` or `restart` per service
44
+ - **Inline log panel** — tail logs for the selected service without leaving the list view, with search (`/`)
45
+ - **Full log view** — scrollable full-screen log viewer with live auto-scroll and search (`/`, `n`/`N`)
46
+ - **Start / Stop / Restart / Rebuild** full container lifecycle management per service
47
+ - **No cache mode** — toggle to force a full clean rebuild (`--no-cache` + `--force-recreate`), off by default
48
+ - **Docker Compose Watch** — toggle `docker compose watch` per service, with live output in the log panel
49
+ - **Dependency-aware rebuild** — rebuild a service then automatically restart all its transitive dependents in topological order
50
+ - **Container exec** — run commands inside any container, inline in the bottom panel (`e`) or full-screen (`x`), with `cd` support and command history
43
51
  - **Vim keybindings** — navigate with `j`/`k`, `G`/`gg`, and more
44
52
 
45
53
  ## Full Log View
46
54
 
47
55
  ![recomposable full logs view](screenshots/logs-view.png)
48
56
 
57
+ ## Exec Mode
58
+
59
+ Run commands inside any running container without leaving the TUI. Press `e` for inline exec in the bottom panel, or `x` for full-screen exec. `cd` works — the working directory is tracked across commands.
60
+
61
+ ![recomposable exec view](screenshots/exec-view.png)
62
+
63
+ ## Docker Compose Watch
64
+
65
+ Press `w` to toggle `docker compose watch` for a service. A cyan `W` indicator appears next to watched services, and watch output streams to the inline log panel. Requires Docker Compose v2.22+.
66
+
67
+ ## Dependency-Aware Rebuild
68
+
69
+ Press `d` to rebuild the selected service and then automatically restart all services that depend on it (transitively), in the correct topological order. Progress is shown step-by-step in the log panel. If the service has no dependents, falls back to a regular rebuild.
70
+
49
71
  ## Adding Compose Files
50
72
 
51
73
  Create a `recomposable.json` file in your project root:
@@ -54,9 +76,7 @@ Create a `recomposable.json` file in your project root:
54
76
  {
55
77
  "composeFiles": [
56
78
  "docker-compose.yml"
57
- ],
58
- "pollInterval": 3000,
59
- "logTailLines": 100
79
+ ]
60
80
  }
61
81
  ```
62
82
 
@@ -87,34 +107,81 @@ recomposable -f docker-compose.yml -f docker-compose.prod.yml
87
107
  |---|---|---|
88
108
  | `composeFiles` | `[]` | Array of docker-compose file paths (relative to `recomposable.json`) |
89
109
  | `pollInterval` | `3000` | Status polling interval in milliseconds |
90
- | `logTailLines` | `100` | Number of log lines to show when entering log view |
110
+ | `logTailLines` | `100` | Number of log lines to show when entering full log view |
91
111
  | `logScanPatterns` | `["WRN]", "ERR]"]` | Patterns to count in container logs |
92
112
  | `logScanLines` | `1000` | Number of log lines to scan for pattern counts |
93
113
  | `logScanInterval` | `10000` | Pattern scanning interval in milliseconds |
114
+ | `bottomLogCount` | `10` | Number of log lines shown in the inline log panel |
115
+ | `statsInterval` | `5000` | CPU/memory polling interval in milliseconds |
116
+ | `statsBufferSize` | `6` | Number of samples for rolling average (e.g. 6 x 5s = 30s window) |
117
+ | `cpuWarnThreshold` | `50` | CPU % above which the column turns yellow |
118
+ | `cpuDangerThreshold` | `100` | CPU % above which the column turns red |
119
+ | `memWarnThreshold` | `512` | Memory in MB above which the column turns yellow |
120
+ | `memDangerThreshold` | `1024` | Memory in MB above which the column turns red |
94
121
 
95
122
  ## Keybindings
96
123
 
124
+ ### List view
125
+
97
126
  | Key | Action |
98
127
  |---|---|
99
128
  | `j` / `Down` | Move cursor down |
100
129
  | `k` / `Up` | Move cursor up |
101
- | `s` | Restart selected service |
102
- | `r` | Rebuild selected service (`up -d --build`) |
130
+ | `s` | Start (if stopped) or restart (if running) |
131
+ | `p` | Stop selected service |
132
+ | `b` | Rebuild selected service (`up -d --build`) |
133
+ | `d` | Dependency-aware rebuild (rebuild + restart all dependents) |
134
+ | `w` | Toggle Docker Compose Watch for selected service |
135
+ | `e` | Inline exec in bottom panel |
136
+ | `x` | Full-screen exec mode |
137
+ | `n` | Toggle no-cache mode (rebuild with `--no-cache` + `--force-recreate`) |
103
138
  | `f` / `Enter` | Full-screen log view for selected service |
104
139
  | `l` | Toggle inline log panel |
140
+ | `/` | Search in inline log panel |
105
141
  | `G` | Jump to bottom |
106
142
  | `gg` | Jump to top |
107
- | `Esc` | Exit log view |
108
143
  | `q` | Quit |
109
144
 
145
+ ### Full log view
146
+
147
+ | Key | Action |
148
+ |---|---|
149
+ | `j` / `Down` | Scroll down |
150
+ | `k` / `Up` | Scroll up |
151
+ | `Ctrl+D` | Page down |
152
+ | `Ctrl+U` | Page up |
153
+ | `G` | Jump to bottom (live mode) |
154
+ | `gg` | Jump to top |
155
+ | `/` | Search logs |
156
+ | `n` | Next search match |
157
+ | `N` | Previous search match |
158
+ | `Esc` / `f` | Exit log view |
159
+ | `q` | Quit |
160
+
161
+ ### Exec mode (inline & full-screen)
162
+
163
+ | Key | Action |
164
+ |---|---|
165
+ | Type | Enter commands |
166
+ | `Enter` | Execute command |
167
+ | `Up` / `Down` | Navigate command history |
168
+ | `x` | Expand inline exec to full screen |
169
+ | `Ctrl+C` | Kill running command (double to quit) |
170
+ | `Esc` | Exit exec mode |
171
+
110
172
  ## Status Icons
111
173
 
112
174
  | Icon | Meaning |
113
175
  |---|---|
114
176
  | Green circle | Running (healthy) |
115
177
  | Red circle | Running (unhealthy) |
116
- | Yellow circle | Rebuilding / Restarting |
178
+ | Yellow circle | Rebuilding / Restarting / Starting / Stopping |
117
179
  | Gray circle | Stopped |
180
+ | Cyan `W` | Docker Compose Watch active |
181
+
182
+ ## Todo
183
+
184
+ - Log search should search all container logs, not only the lines currently tailed by the tool
118
185
 
119
186
  ## Requirements
120
187
 
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import type { Config, AppState, ServiceGroup } from './lib/types';
3
+ export interface ModuleState {
4
+ logScanActive: boolean;
5
+ statsPollActive: boolean;
6
+ lastRenderTime: number;
7
+ pendingRender: ReturnType<typeof setTimeout> | null;
8
+ logFetchTimer: ReturnType<typeof setTimeout> | null;
9
+ }
10
+ export declare function createModuleState(): ModuleState;
11
+ export declare function loadConfig(): Config;
12
+ export declare function discoverServices(config: Config): ServiceGroup[];
13
+ export declare function pollStatuses(state: AppState): void;
14
+ export declare function pollLogCounts(state: AppState): void;
15
+ export declare function pollContainerStats(state: AppState): void;
16
+ export declare function render(state: AppState): void;
17
+ export declare function stripAnsi(str: string): string;
18
+ export declare function throttledRender(state: AppState): void;
19
+ export declare function updateSelectedLogs(state: AppState): void;
20
+ export declare function doRebuild(state: AppState): void;
21
+ export declare function doRestart(state: AppState): void;
22
+ export declare function doStop(state: AppState): void;
23
+ export declare function doStart(state: AppState): void;
24
+ export declare function doWatch(state: AppState): void;
25
+ export declare function initDepGraphs(state: AppState): void;
26
+ export declare function doCascadeRebuild(state: AppState): void;
27
+ export declare function enterExecInline(state: AppState): void;
28
+ export declare function enterExec(state: AppState): void;
29
+ export declare function exitExec(state: AppState): void;
30
+ export declare function runExecCommand(state: AppState): void;
31
+ export declare function enterLogs(state: AppState): void;
32
+ export declare function exitLogs(state: AppState): void;
33
+ export declare function executeLogSearch(state: AppState): void;
34
+ export declare function jumpToNextMatch(state: AppState): void;
35
+ export declare function jumpToPrevMatch(state: AppState): void;
36
+ export declare function handleKeypress(state: AppState, key: string): void;
37
+ export declare function createInputHandler(state: AppState): (data: Buffer | string) => void;
38
+ export declare function cleanup(state: AppState): void;
39
+ export declare function _getModuleState(): ModuleState;
40
+ export declare function _setModuleState(ms: ModuleState): void;