start-command 0.7.5 → 0.9.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.
@@ -0,0 +1,297 @@
1
+ # Architecture
2
+
3
+ This document describes the architecture of the `$` command (start-command).
4
+
5
+ ## Overview
6
+
7
+ The start-command is a CLI tool that wraps shell commands to provide automatic logging, error reporting, natural language aliases, and process isolation capabilities.
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────────────────┐
11
+ │ User Command │
12
+ │ $ [options] command [args] │
13
+ └──────────────────────────────┬──────────────────────────────────────┘
14
+
15
+
16
+ ┌─────────────────────────────────────────────────────────────────────┐
17
+ │ CLI Entry Point │
18
+ │ src/bin/cli.js │
19
+ ├─────────────────────────────────────────────────────────────────────┤
20
+ │ • Parse command line arguments │
21
+ │ • Handle --version, --help flags │
22
+ │ • Route to isolation or direct execution │
23
+ └──────────────────────────────┬──────────────────────────────────────┘
24
+
25
+ ┌────────────────┴────────────────┐
26
+ │ │
27
+ ▼ ▼
28
+ ┌─────────────────────────┐ ┌─────────────────────────────────────┐
29
+ │ Direct Execution │ │ Isolated Execution │
30
+ │ (no --isolated) │ │ (--isolated screen/tmux/docker) │
31
+ ├─────────────────────────┤ ├─────────────────────────────────────┤
32
+ │ • Spawn shell process │ │ src/lib/isolation.js │
33
+ │ • Capture stdout/stderr │ │ • runInScreen() │
34
+ │ • Log to temp file │ │ • runInTmux() │
35
+ │ • Report failures │ │ • runInDocker() │
36
+ └─────────────────────────┘ └─────────────────────────────────────┘
37
+ ```
38
+
39
+ ## Core Modules
40
+
41
+ ### 1. CLI Entry Point (`src/bin/cli.js`)
42
+
43
+ The main entry point that:
44
+
45
+ - Parses command line arguments using `args-parser.js`
46
+ - Processes command substitutions using `substitution.js`
47
+ - Routes execution to direct mode or isolation mode
48
+ - Handles logging and error reporting
49
+
50
+ ### 2. Argument Parser (`src/lib/args-parser.js`)
51
+
52
+ Parses wrapper options and extracts the command to execute:
53
+
54
+ ```javascript
55
+ {
56
+ isolated: null, // 'screen' | 'tmux' | 'docker' | null
57
+ attached: false, // Run in attached/foreground mode
58
+ detached: false, // Run in detached/background mode
59
+ session: null, // Custom session name
60
+ image: null, // Docker image name
61
+ keepAlive: false, // Keep environment alive after command exits
62
+ }
63
+ ```
64
+
65
+ ### 3. Substitution Engine (`src/lib/substitution.js`)
66
+
67
+ Provides natural language command aliases:
68
+
69
+ - Loads patterns from `substitutions.lino`
70
+ - Matches user input against patterns with variables
71
+ - Returns substituted command or original if no match
72
+
73
+ ### 4. Isolation Module (`src/lib/isolation.js`)
74
+
75
+ Handles process isolation in terminal multiplexers and containers:
76
+
77
+ ```
78
+ ┌────────────────────────────────────────────────────────────┐
79
+ │ runIsolated() │
80
+ │ (dispatcher function) │
81
+ └───────────────┬───────────────┬───────────────┬────────────┘
82
+ │ │ │
83
+ ┌───────▼───────┐ ┌─────▼─────┐ ┌───────▼───────┐
84
+ │ runInScreen │ │runInTmux │ │ runInDocker │
85
+ │ │ │ │ │ │
86
+ │ GNU Screen │ │ tmux │ │ Docker │
87
+ │ multiplexer │ │ terminal │ │ containers │
88
+ └───────────────┘ └───────────┘ └───────────────┘
89
+ ```
90
+
91
+ ## Isolation Architecture
92
+
93
+ ### Execution Modes
94
+
95
+ | Mode | Description | Default Behavior |
96
+ | ------------ | ------------------------------------------- | ------------------------------ |
97
+ | Attached | Command runs in foreground, interactive | Session exits after completion |
98
+ | Detached | Command runs in background | Session exits after completion |
99
+ | + Keep-Alive | Session stays alive after command completes | Requires `--keep-alive` flag |
100
+
101
+ ### Auto-Exit Behavior
102
+
103
+ By default, all isolation environments automatically exit after command completion:
104
+
105
+ ```
106
+ ┌───────────────────────────────────────────────────────────────┐
107
+ │ Default (keepAlive=false) │
108
+ ├───────────────────────────────────────────────────────────────┤
109
+ │ 1. Start isolation environment │
110
+ │ 2. Execute command │
111
+ │ 3. Capture output (if attached mode) │
112
+ │ 4. Environment exits automatically │
113
+ │ 5. Resources freed │
114
+ └───────────────────────────────────────────────────────────────┘
115
+
116
+ ┌───────────────────────────────────────────────────────────────┐
117
+ │ With --keep-alive │
118
+ ├───────────────────────────────────────────────────────────────┤
119
+ │ 1. Start isolation environment │
120
+ │ 2. Execute command │
121
+ │ 3. Command completes │
122
+ │ 4. Shell stays running in session │
123
+ │ 5. User can reattach and interact │
124
+ └───────────────────────────────────────────────────────────────┘
125
+ ```
126
+
127
+ ### Screen Isolation
128
+
129
+ ```
130
+ ┌─────────────────────────────────────────────────────────────────┐
131
+ │ Screen Execution Flow │
132
+ ├─────────────────────────────────────────────────────────────────┤
133
+ │ │
134
+ │ Attached Mode: │
135
+ │ ┌─────────────────────────────────────────────────────────┐ │
136
+ │ │ Uses detached mode with log capture internally │ │
137
+ │ │ • Start: screen -dmS <session> -L -Logfile <log> │ │
138
+ │ │ • Poll for session completion │ │
139
+ │ │ • Read and display captured output │ │
140
+ │ │ • Clean up log file │ │
141
+ │ └─────────────────────────────────────────────────────────┘ │
142
+ │ │
143
+ │ Detached Mode: │
144
+ │ ┌─────────────────────────────────────────────────────────┐ │
145
+ │ │ • Without keep-alive: screen -dmS <session> sh -c cmd │ │
146
+ │ │ • With keep-alive: screen -dmS <session> sh -c "cmd; sh"│ │
147
+ │ └─────────────────────────────────────────────────────────┘ │
148
+ │ │
149
+ └─────────────────────────────────────────────────────────────────┘
150
+ ```
151
+
152
+ ### tmux Isolation
153
+
154
+ ```
155
+ ┌─────────────────────────────────────────────────────────────────┐
156
+ │ tmux Execution Flow │
157
+ ├─────────────────────────────────────────────────────────────────┤
158
+ │ │
159
+ │ Attached Mode: │
160
+ │ ┌─────────────────────────────────────────────────────────┐ │
161
+ │ │ • tmux new-session -s <session> <command> │ │
162
+ │ │ • Interactive, exits when command completes │ │
163
+ │ └─────────────────────────────────────────────────────────┘ │
164
+ │ │
165
+ │ Detached Mode: │
166
+ │ ┌─────────────────────────────────────────────────────────┐ │
167
+ │ │ • Without keep-alive: tmux new-session -d -s <session> │ │
168
+ │ │ • With keep-alive: command followed by shell exec │ │
169
+ │ └─────────────────────────────────────────────────────────┘ │
170
+ │ │
171
+ └─────────────────────────────────────────────────────────────────┘
172
+ ```
173
+
174
+ ### Docker Isolation
175
+
176
+ ```
177
+ ┌─────────────────────────────────────────────────────────────────┐
178
+ │ Docker Execution Flow │
179
+ ├─────────────────────────────────────────────────────────────────┤
180
+ │ │
181
+ │ Attached Mode: │
182
+ │ ┌─────────────────────────────────────────────────────────┐ │
183
+ │ │ • docker run -it --rm --name <name> <image> sh -c cmd │ │
184
+ │ │ • Interactive, container auto-removed on exit │ │
185
+ │ └─────────────────────────────────────────────────────────┘ │
186
+ │ │
187
+ │ Detached Mode: │
188
+ │ ┌─────────────────────────────────────────────────────────┐ │
189
+ │ │ • Without keep-alive: docker run -d --name <name> ... │ │
190
+ │ │ • With keep-alive: command followed by shell exec │ │
191
+ │ └─────────────────────────────────────────────────────────┘ │
192
+ │ │
193
+ └─────────────────────────────────────────────────────────────────┘
194
+ ```
195
+
196
+ ## Logging Architecture
197
+
198
+ ```
199
+ ┌─────────────────────────────────────────────────────────────────┐
200
+ │ Logging Flow │
201
+ ├─────────────────────────────────────────────────────────────────┤
202
+ │ │
203
+ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────────┐ │
204
+ │ │ Command │───▶│ Capture │───▶│ Write to │ │
205
+ │ │ Execution │ │ stdout/stderr│ │ Temp Log File │ │
206
+ │ └─────────────┘ └──────────────┘ └───────────────────┘ │
207
+ │ │
208
+ │ Log File Format: │
209
+ │ ┌─────────────────────────────────────────────────────────┐ │
210
+ │ │ === Start Command Log === │ │
211
+ │ │ Timestamp: 2024-01-15 10:30:45 │ │
212
+ │ │ Command: <command> │ │
213
+ │ │ Shell: /bin/bash │ │
214
+ │ │ Platform: linux │ │
215
+ │ │ ================================================== │ │
216
+ │ │ <command output> │ │
217
+ │ │ ================================================== │ │
218
+ │ │ Finished: 2024-01-15 10:30:46 │ │
219
+ │ │ Exit Code: 0 │ │
220
+ │ └─────────────────────────────────────────────────────────┘ │
221
+ │ │
222
+ └─────────────────────────────────────────────────────────────────┘
223
+ ```
224
+
225
+ ## File Structure
226
+
227
+ ```
228
+ start-command/
229
+ ├── src/
230
+ │ ├── bin/
231
+ │ │ └── cli.js # Main entry point
232
+ │ └── lib/
233
+ │ ├── args-parser.js # Argument parsing
234
+ │ ├── isolation.js # Isolation backends
235
+ │ ├── substitution.js # Command aliases
236
+ │ └── substitutions.lino # Alias patterns
237
+ ├── test/
238
+ │ ├── cli.test.js # CLI tests
239
+ │ ├── isolation.test.js # Isolation tests
240
+ │ ├── args-parser.test.js # Parser tests
241
+ │ └── substitution.test.js # Substitution tests
242
+ ├── docs/
243
+ │ ├── PIPES.md # Piping documentation
244
+ │ └── USAGE.md # Usage examples
245
+ ├── experiments/ # Experimental scripts
246
+ ├── REQUIREMENTS.md # Requirements specification
247
+ ├── ARCHITECTURE.md # This file
248
+ └── README.md # Project overview
249
+ ```
250
+
251
+ ## Design Decisions
252
+
253
+ ### 1. Auto-Exit by Default
254
+
255
+ All isolation environments exit automatically after command completion to:
256
+
257
+ - Prevent resource leaks from orphaned sessions
258
+ - Ensure consistent behavior across backends
259
+ - Match user expectations for command execution
260
+
261
+ ### 2. Log Capture in Attached Screen Mode
262
+
263
+ Screen's attached mode uses internal detached mode with log capture because:
264
+
265
+ - Direct attached mode loses output for quick commands
266
+ - Screen's virtual terminal is destroyed before output is visible
267
+ - Log capture ensures reliable output preservation
268
+
269
+ ### 3. Keep-Alive as Opt-In
270
+
271
+ The `--keep-alive` flag is disabled by default because:
272
+
273
+ - Most use cases don't require persistent sessions
274
+ - Prevents accidental resource consumption
275
+ - Explicit opt-in for advanced workflows
276
+
277
+ ### 4. Uniform Backend Interface
278
+
279
+ All isolation backends share a consistent interface:
280
+
281
+ ```javascript
282
+ async function runInBackend(command, options) {
283
+ return {
284
+ success: boolean,
285
+ sessionName: string,
286
+ message: string,
287
+ exitCode?: number,
288
+ output?: string
289
+ };
290
+ }
291
+ ```
292
+
293
+ This enables:
294
+
295
+ - Easy addition of new backends
296
+ - Consistent error handling
297
+ - Unified logging format
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # start-command
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c484149: Add --keep-alive option for isolation environments
8
+ - All isolation environments (screen, tmux, docker) now automatically exit after command completion by default
9
+ - New --keep-alive (-k) flag keeps the isolation environment running after command completes
10
+ - Add ARCHITECTURE.md documentation describing system design
11
+ - Update REQUIREMENTS.md with new option and auto-exit behavior documentation
12
+
13
+ ## 0.7.6
14
+
15
+ ### Patch Changes
16
+
17
+ - a5fca3f: Add documentation for piping with `$` command
18
+ - Created `docs/PIPES.md` with detailed guide on pipe usage
19
+ - Preferred approach: `echo "hi" | $ agent` (pipe TO the $-wrapped command)
20
+ - Alternative approach: `$ 'echo "hi" | agent'` (quoting)
21
+ - Updated `docs/USAGE.md` with brief pipe reference
22
+ - Updated `README.md` with piping examples
23
+ - Updated case study for issue #28 with new recommended approach
24
+
3
25
  ## 0.7.5
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -21,6 +21,29 @@ $ npm test
21
21
  $ git status
22
22
  ```
23
23
 
24
+ ### Piping with `$`
25
+
26
+ When piping data to a command wrapped with `$`, **put `$` on the receiving command**:
27
+
28
+ ```bash
29
+ # Preferred - pipe TO the $-wrapped command
30
+ echo "hi" | $ agent
31
+
32
+ # Alternative - quote the entire pipeline (more verbose)
33
+ $ 'echo "hi" | agent'
34
+ ```
35
+
36
+ Both approaches work, but piping TO `$` is simpler and requires fewer quotes.
37
+
38
+ ```bash
39
+ # More examples
40
+ cat file.txt | $ processor
41
+ git diff | $ reviewer
42
+ echo "analyze this" | $ agent --verbose
43
+ ```
44
+
45
+ See [docs/PIPES.md](docs/PIPES.md) for detailed guidance on piping, and [docs/USAGE.md](docs/USAGE.md) for general usage.
46
+
24
47
  ### Natural Language Commands (Aliases)
25
48
 
26
49
  You can also use natural language to execute common commands. The `$` command supports pattern-based substitutions defined in `substitutions.lino`:
@@ -139,16 +162,37 @@ $ -i tmux -s my-session -d bun start
139
162
 
140
163
  #### Isolation Options
141
164
 
142
- | Option | Description |
143
- | ---------------- | -------------------------------------------- |
144
- | `--isolated, -i` | Isolation backend (screen, tmux, docker) |
145
- | `--attached, -a` | Run in attached/foreground mode (default) |
146
- | `--detached, -d` | Run in detached/background mode |
147
- | `--session, -s` | Custom session/container name |
148
- | `--image` | Docker image (required for docker isolation) |
165
+ | Option | Description |
166
+ | -------------------------------- | ----------------------------------------------------- |
167
+ | `--isolated, -i` | Isolation backend (screen, tmux, docker) |
168
+ | `--attached, -a` | Run in attached/foreground mode (default) |
169
+ | `--detached, -d` | Run in detached/background mode |
170
+ | `--session, -s` | Custom session/container name |
171
+ | `--image` | Docker image (required for docker isolation) |
172
+ | `--keep-alive, -k` | Keep session alive after command completes |
173
+ | `--auto-remove-docker-container` | Auto-remove docker container after exit (docker only) |
149
174
 
150
175
  **Note:** Using both `--attached` and `--detached` together will result in an error - you must choose one mode.
151
176
 
177
+ #### Auto-Exit Behavior
178
+
179
+ By default, all isolation environments (screen, tmux, docker) automatically exit after the target command completes. This ensures resources are freed immediately and provides uniform behavior across all backends.
180
+
181
+ Use `--keep-alive` (`-k`) to keep the session running after command completion:
182
+
183
+ ```bash
184
+ # Default: session exits after command completes
185
+ $ -i screen -d -- echo "hello"
186
+ # Session will exit automatically after command completes.
187
+
188
+ # With --keep-alive: session stays running for interaction
189
+ $ -i screen -d -k -- echo "hello"
190
+ # Session will stay alive after command completes.
191
+ # You can reattach with: screen -r <session-name>
192
+ ```
193
+
194
+ For Docker containers, by default the container filesystem is preserved (appears in `docker ps -a`) so you can re-enter it later. Use `--auto-remove-docker-container` to remove the container immediately after exit.
195
+
152
196
  ### Graceful Degradation
153
197
 
154
198
  The tool works in any environment:
package/REQUIREMENTS.md CHANGED
@@ -142,6 +142,8 @@ Support two patterns for passing wrapper options:
142
142
  - `--detached, -d`: Run in detached/background mode
143
143
  - `--session, -s <name>`: Custom session name
144
144
  - `--image <image>`: Docker image (required for docker backend)
145
+ - `--keep-alive, -k`: Keep isolation environment alive after command exits (disabled by default)
146
+ - `--auto-remove-docker-container`: Automatically remove docker container after exit (disabled by default, only valid with --isolated docker)
145
147
 
146
148
  #### 6.3 Supported Backends
147
149
 
@@ -155,7 +157,30 @@ Support two patterns for passing wrapper options:
155
157
  - **Detached mode**: Command runs in background, session info displayed for reattachment
156
158
  - **Conflict handling**: If both --attached and --detached are specified, show error asking user to choose one
157
159
 
158
- #### 6.5 Graceful Degradation
160
+ #### 6.5 Auto-Exit Behavior
161
+
162
+ By default, all isolation environments (screen, tmux, docker) automatically exit after the target command completes execution. This ensures:
163
+
164
+ - Resources are freed immediately after command execution
165
+ - No orphaned sessions/containers remain running
166
+ - Uniform behavior across all isolation backends
167
+ - Command output is still captured and logged before exit
168
+
169
+ The `--keep-alive` flag can be used to override this behavior and keep the isolation environment running after command completion, useful for debugging or interactive workflows.
170
+
171
+ **Docker Container Filesystem Preservation:**
172
+ By default, when using Docker isolation, the container filesystem is preserved after the container exits. This allows you to re-enter the container and access any files created during command execution, which is useful for retrieving additional output files or debugging. The container appears in `docker ps -a` in an "exited" state but is not removed.
173
+
174
+ The `--auto-remove-docker-container` flag enables automatic removal of the container after exit, which is useful when you don't need to preserve the container filesystem and want to clean up resources completely. When this flag is enabled:
175
+
176
+ - The container is removed immediately after exiting (using docker's `--rm` flag)
177
+ - The container will not appear in `docker ps -a` after command completion
178
+ - You cannot re-enter the container to access files
179
+ - Resources are freed more aggressively
180
+
181
+ Note: `--auto-remove-docker-container` is only valid with `--isolated docker` and is independent of the `--keep-alive` flag.
182
+
183
+ #### 6.6 Graceful Degradation
159
184
 
160
185
  - If isolation backend is not installed, show informative error with installation instructions
161
186
  - If session creation fails, report error with details