start-command 0.13.0 → 0.15.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +28 -231
  2. package/bun.lock +5 -0
  3. package/eslint.config.mjs +1 -1
  4. package/package.json +11 -6
  5. package/src/bin/cli.js +275 -137
  6. package/src/lib/args-parser.js +118 -0
  7. package/src/lib/execution-store.js +722 -0
  8. package/src/lib/isolation.js +51 -0
  9. package/src/lib/status-formatter.js +121 -0
  10. package/src/lib/version.js +143 -0
  11. package/test/args-parser.test.js +107 -0
  12. package/test/cli.test.js +11 -1
  13. package/test/docker-autoremove.test.js +11 -16
  14. package/test/execution-store.test.js +483 -0
  15. package/test/isolation-cleanup.test.js +11 -16
  16. package/test/isolation.test.js +11 -17
  17. package/test/public-exports.test.js +105 -0
  18. package/test/status-query.test.js +195 -0
  19. package/.github/workflows/release.yml +0 -352
  20. package/.husky/pre-commit +0 -1
  21. package/ARCHITECTURE.md +0 -297
  22. package/LICENSE +0 -24
  23. package/README.md +0 -339
  24. package/REQUIREMENTS.md +0 -299
  25. package/docs/PIPES.md +0 -243
  26. package/docs/USAGE.md +0 -194
  27. package/docs/case-studies/issue-15/README.md +0 -208
  28. package/docs/case-studies/issue-18/README.md +0 -343
  29. package/docs/case-studies/issue-18/issue-comments.json +0 -1
  30. package/docs/case-studies/issue-18/issue-data.json +0 -7
  31. package/docs/case-studies/issue-22/analysis.md +0 -547
  32. package/docs/case-studies/issue-22/issue-data.json +0 -12
  33. package/docs/case-studies/issue-25/README.md +0 -232
  34. package/docs/case-studies/issue-25/issue-data.json +0 -21
  35. package/docs/case-studies/issue-28/README.md +0 -405
  36. package/docs/case-studies/issue-28/issue-data.json +0 -105
  37. package/docs/case-studies/issue-28/raw-issue-data.md +0 -92
  38. package/experiments/debug-regex.js +0 -49
  39. package/experiments/isolation-design.md +0 -131
  40. package/experiments/screen-output-test.js +0 -265
  41. package/experiments/test-cli.sh +0 -42
  42. package/experiments/test-command-stream-cjs.cjs +0 -30
  43. package/experiments/test-command-stream-wrapper.js +0 -54
  44. package/experiments/test-command-stream.mjs +0 -56
  45. package/experiments/test-screen-attached.js +0 -126
  46. package/experiments/test-screen-logfile.js +0 -286
  47. package/experiments/test-screen-modes.js +0 -128
  48. package/experiments/test-screen-output.sh +0 -27
  49. package/experiments/test-screen-tee-debug.js +0 -237
  50. package/experiments/test-screen-tee-fallback.js +0 -230
  51. package/experiments/test-substitution.js +0 -143
  52. package/experiments/user-isolation-research.md +0 -83
  53. package/scripts/changeset-version.mjs +0 -38
  54. package/scripts/check-file-size.mjs +0 -103
  55. package/scripts/create-github-release.mjs +0 -93
  56. package/scripts/create-manual-changeset.mjs +0 -89
  57. package/scripts/format-github-release.mjs +0 -83
  58. package/scripts/format-release-notes.mjs +0 -219
  59. package/scripts/instant-version-bump.mjs +0 -121
  60. package/scripts/publish-to-npm.mjs +0 -129
  61. package/scripts/setup-npm.mjs +0 -37
  62. package/scripts/validate-changeset.mjs +0 -107
  63. package/scripts/version-and-commit.mjs +0 -237
package/docs/USAGE.md DELETED
@@ -1,194 +0,0 @@
1
- # start-command Usage Guide
2
-
3
- This document provides detailed guidance on using the `$` command effectively, including important information about shell quoting and special characters.
4
-
5
- ## Table of Contents
6
-
7
- - [Quick Start](#quick-start)
8
- - [Using Pipes](#using-pipes)
9
- - [Shell Metacharacters](#shell-metacharacters)
10
- - [Quoting Reference](#quoting-reference)
11
- - [Command Examples](#command-examples)
12
- - [Troubleshooting](#troubleshooting)
13
-
14
- ## Quick Start
15
-
16
- The `$` command wraps any shell command with automatic logging and failure reporting:
17
-
18
- ```bash
19
- $ echo "Hello World"
20
- $ npm test
21
- $ git status
22
- ```
23
-
24
- ## Using Pipes
25
-
26
- When piping data to a command wrapped with `$`, there are two approaches. **The preferred way is to pipe TO the `$`-wrapped command**:
27
-
28
- ```bash
29
- # Preferred - pipe TO the $-wrapped command
30
- echo "hi" | $ agent
31
-
32
- # Alternative - quote the entire pipeline
33
- $ 'echo "hi" | agent'
34
- ```
35
-
36
- The first approach is simpler and requires fewer quotes. For detailed information about piping, see **[PIPES.md](PIPES.md)**.
37
-
38
- ### Quick Examples
39
-
40
- ```bash
41
- # Pipe text to an AI agent
42
- echo "Explain this code" | $ agent
43
-
44
- # Pipe file contents to a processor
45
- cat file.txt | $ processor
46
-
47
- # Chain commands, wrap the final one
48
- git diff | $ reviewer
49
- ```
50
-
51
- ## Shell Metacharacters
52
-
53
- The following characters are interpreted by the shell before reaching `$`:
54
-
55
- | Character | Name | Purpose |
56
- | --------- | ---------- | ------------------------------------- |
57
- | `\|` | Pipe | Connects stdout to stdin |
58
- | `&` | Background | Runs command in background |
59
- | `;` | Semicolon | Command separator |
60
- | `&&` | AND | Run next command if previous succeeds |
61
- | `\|\|` | OR | Run next command if previous fails |
62
- | `>` | Redirect | Redirect stdout to file |
63
- | `<` | Input | Read input from file |
64
- | `$` | Variable | Variable expansion |
65
- | `` ` `` | Backtick | Command substitution |
66
- | `*?[]` | Globs | Filename expansion |
67
-
68
- ## Quoting Reference
69
-
70
- When you need to pass special characters literally to `$`, use quotes:
71
-
72
- | Quote Type | Behavior | Use When |
73
- | ----------- | -------------------------------------- | --------------------------------------- |
74
- | `'single'` | Everything is literal, no expansion | Preserving pipes, special chars exactly |
75
- | `"double"` | Variables expand, some escaping needed | Need variable expansion inside |
76
- | `$'...'` | ANSI-C quoting, escape sequences work | Need escape sequences like `\n`, `\t` |
77
- | `` `...` `` | Command substitution (old style) | Capturing command output (prefer `$()`) |
78
-
79
- ### Examples with Different Quote Styles
80
-
81
- ```bash
82
- # Single quotes - everything literal
83
- $ 'echo "hello" | wc -c'
84
-
85
- # Double quotes - variables expand
86
- $ "echo $HOME | wc -c" # $HOME expands first!
87
-
88
- # Double quotes with escaping
89
- $ "echo \$HOME | wc -c" # \$ keeps it literal
90
- ```
91
-
92
- ## Command Examples
93
-
94
- ### Simple Commands (No Quoting Needed)
95
-
96
- ```bash
97
- $ ls -la
98
- $ npm test
99
- $ git status
100
- $ echo "hello world"
101
- ```
102
-
103
- ### Commands with Pipes
104
-
105
- ```bash
106
- # Preferred: pipe TO the $-wrapped command
107
- echo "hello" | $ grep "h"
108
- cat file.txt | $ processor
109
- git log | $ reviewer
110
-
111
- # Alternative: quote the entire pipeline
112
- $ 'cat file.txt | grep pattern'
113
- $ 'ps aux | grep node'
114
- ```
115
-
116
- ### Commands with Redirection (Quoting Required)
117
-
118
- ```bash
119
- $ 'echo "data" > output.txt'
120
- $ 'cat < input.txt'
121
- $ 'npm test 2>&1 | tee test.log'
122
- ```
123
-
124
- ### Commands with Logical Operators (Quoting Required)
125
-
126
- ```bash
127
- $ 'npm install && npm test'
128
- $ 'command1 || command2'
129
- $ 'test -f file && cat file'
130
- ```
131
-
132
- ### Commands with Background Processes (Quoting Required)
133
-
134
- ```bash
135
- $ 'npm start &'
136
- $ 'sleep 10 && echo "done" &'
137
- ```
138
-
139
- ### Commands with Variables
140
-
141
- ```bash
142
- # Variable expands BEFORE $ sees it (usually what you want)
143
- $ echo "$HOME"
144
-
145
- # Variable is passed literally to $ (rare use case)
146
- $ 'echo $HOME'
147
- ```
148
-
149
- ## Troubleshooting
150
-
151
- ### Problem: Pipe Output Goes to Wrong Place
152
-
153
- **Symptom:** Running `$ cmd1 | cmd2` and cmd2 receives unexpected output.
154
-
155
- **Solutions:**
156
-
157
- 1. Pipe TO $: `cmd1 | $ cmd2` (preferred)
158
- 2. Quote: `$ 'cmd1 | cmd2'`
159
-
160
- ### Problem: Variables Not Expanding
161
-
162
- **Symptom:** `$ 'echo $HOME'` literally prints "$HOME"
163
-
164
- **Solution:** Use double quotes: `$ "echo $HOME"` or pipe: `echo "$HOME" | $ processor`
165
-
166
- ### Problem: Special Characters Causing Errors
167
-
168
- **Symptom:** Commands with `*`, `?`, `[`, `]` behave unexpectedly
169
-
170
- **Solution:** Quote the command or escape the characters:
171
-
172
- ```bash
173
- $ 'ls *.txt' # Quotes prevent glob expansion by outer shell
174
- $ ls \*.txt # Escape prevents expansion
175
- ```
176
-
177
- ### Problem: Command with Internal Quotes
178
-
179
- **Symptom:** `$ 'echo "hello 'world'"'` causes syntax errors
180
-
181
- **Solution:** Use different quote styles or escape:
182
-
183
- ```bash
184
- $ "echo \"hello 'world'\"" # Use double quotes with escaping
185
- $ $'echo "hello \'world\'"' # Use ANSI-C quoting
186
- ```
187
-
188
- ## Further Reading
189
-
190
- - [PIPES.md](PIPES.md) - Detailed guide on piping with `$`
191
- - [Bash Reference Manual - Quoting](https://www.gnu.org/software/bash/manual/html_node/Quoting.html)
192
- - [Bash Reference Manual - Pipelines](https://www.gnu.org/software/bash/manual/html_node/Pipelines.html)
193
- - [POSIX Shell Command Language](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html)
194
- - [Case Study: Issue #28 - Shell Quoting Analysis](case-studies/issue-28/README.md)
@@ -1,208 +0,0 @@
1
- # Case Study: Issue #15 - Screen Isolation Not Working As Expected
2
-
3
- ## Issue Summary
4
-
5
- **Issue URL:** https://github.com/link-foundation/start/issues/15
6
- **Date Reported:** 2025-12-22
7
- **Reporter:** @konard
8
- **Status:** Investigating
9
-
10
- ### Problem Statement
11
-
12
- The screen isolation environment does not display command output when running in attached mode. When using `$ --isolated screen -- echo "hello"`, the expected output "hello" is not shown - instead, only `[screen is terminating]` appears.
13
-
14
- ### Environment
15
-
16
- - **Platform:** macOS (reported), Linux (reproduced)
17
- - **Package:** start-command@0.5.1
18
- - **Screen version:** macOS bundled 4.0.3, Linux 4.09.01
19
-
20
- ## Timeline of Events
21
-
22
- 1. User installs start-command: `bun install -g start-command`
23
- 2. Direct command execution works: `$ echo "hello"` shows "hello"
24
- 3. Docker isolation works: `$ --isolated docker --image alpine -- echo "hello"` shows "hello"
25
- 4. Screen isolation fails: `$ --isolated screen -- echo "hello"` shows only `[screen is terminating]`
26
-
27
- ## Reproduction
28
-
29
- ### Observed Behavior
30
-
31
- ```
32
- $ echo "hello"
33
- [2025-12-22 13:45:05.245] Starting: echo hello
34
- hello
35
- [2025-12-22 13:45:05.254] Finished
36
- Exit code: 0
37
-
38
- $ --isolated docker --image alpine -- echo "hello"
39
- [2025-12-22 13:45:07.847] Starting: echo hello
40
- [Isolation] Environment: docker, Mode: attached
41
- [Isolation] Image: alpine
42
- hello
43
- Docker container "docker-..." exited with code 0
44
- [2025-12-22 13:45:08.066] Finished
45
- Exit code: 0
46
-
47
- $ --isolated screen -- echo "hello"
48
- [2025-12-22 13:45:11.134] Starting: echo hello
49
- [Isolation] Environment: screen, Mode: attached
50
- [screen is terminating]
51
- Screen session "screen-..." exited with code 0
52
- [2025-12-22 13:45:11.199] Finished
53
- Exit code: 0
54
- ```
55
-
56
- **Notice:** No "hello" output in the screen isolation case, though exit code is 0.
57
-
58
- ## Root Cause Analysis
59
-
60
- ### PRIMARY ROOT CAUSE: macOS Screen Version Incompatibility
61
-
62
- **macOS ships with GNU Screen version 4.0.3, which does NOT support the `-Logfile` option.**
63
-
64
- The `-Logfile` option was introduced in **GNU Screen 4.5.1** (released February 2017).
65
-
66
- | Platform | Screen Version | `-Logfile` Support |
67
- | --------------- | -------------- | ------------------ |
68
- | macOS (bundled) | 4.0.3 | **NO** |
69
- | Linux (CI/Test) | 4.09.01 | YES |
70
-
71
- The current implementation uses:
72
-
73
- ```javascript
74
- const screenArgs = [
75
- '-dmS',
76
- sessionName,
77
- '-L',
78
- '-Logfile',
79
- logFile, // <-- NOT SUPPORTED on macOS bundled screen
80
- shell,
81
- shellArg,
82
- command,
83
- ];
84
- ```
85
-
86
- On macOS with screen 4.0.3:
87
-
88
- 1. The `-Logfile` option is silently ignored or treated as a command argument
89
- 2. The `-L` flag alone creates a log file named `screenlog.0` in the current directory
90
- 3. The code tries to read from the wrong file path (`/tmp/screen-output-*.log`)
91
- 4. Result: No output is captured or displayed
92
-
93
- ### Secondary Root Cause: TTY Requirement
94
-
95
- When TTY is available, the code attempts attached mode which fails:
96
-
97
- 1. **TTY Requirement**: The GNU Screen command requires a connected terminal (TTY/PTY) to run in attached mode.
98
-
99
- 2. **Node.js spawn behavior**: When spawning processes with `child_process.spawn()`, even with `stdio: 'inherit'`, Node.js does not always provide a proper pseudo-terminal (PTY) that screen requires.
100
-
101
- 3. **Error in non-TTY environments**: Running `screen -S session shell -c command` without a TTY results in:
102
-
103
- ```
104
- Must be connected to a terminal.
105
- ```
106
-
107
- 4. **Detached mode works**: Running `screen -dmS session shell -c command` works because it doesn't require an attached terminal.
108
-
109
- ### Experimental Evidence
110
-
111
- Testing revealed:
112
-
113
- - `process.stdin.isTTY` and `process.stdout.isTTY` are `undefined` when running from Node.js
114
- - Detached mode with logging (`screen -dmS ... -L -Logfile ...`) captures output correctly **on Linux only**
115
- - Using `script -q -c "screen ..." /dev/null` can provide a PTY but includes terminal escape codes
116
- - On macOS with screen 4.0.3, the `-Logfile` option is unknown
117
-
118
- ### Version Check Evidence
119
-
120
- ```bash
121
- # Linux (works)
122
- $ screen --version
123
- Screen version 4.09.01 (GNU) 20-Aug-23
124
-
125
- # macOS bundled (broken)
126
- $ screen --version
127
- Screen version 4.00.03 (FAU) 23-Oct-06
128
- ```
129
-
130
- ### Comparison with Docker
131
-
132
- Docker isolation works because:
133
-
134
- 1. Docker run with `-it` flags handles terminal attachment
135
- 2. Docker spawns an isolated container that manages its own pseudo-terminal
136
- 3. The command output flows through Docker's I/O handling
137
-
138
- ## Solution: Version Detection with Fallback
139
-
140
- ### Approach
141
-
142
- 1. **Detect screen version** at runtime
143
- 2. **Version >= 4.5.1**: Use `-L -Logfile` approach
144
- 3. **Version < 4.5.1**: Use output redirection (`tee`) approach within the command
145
-
146
- ### Implementation
147
-
148
- ```javascript
149
- function getScreenVersion() {
150
- try {
151
- const output = execSync('screen --version', { encoding: 'utf8' });
152
- const match = output.match(/(\d+)\.(\d+)\.(\d+)/);
153
- if (match) {
154
- return {
155
- major: parseInt(match[1]),
156
- minor: parseInt(match[2]),
157
- patch: parseInt(match[3]),
158
- };
159
- }
160
- } catch {
161
- return null;
162
- }
163
- return null;
164
- }
165
-
166
- function supportsLogfileOption() {
167
- const version = getScreenVersion();
168
- if (!version) return false;
169
- // -Logfile was added in 4.5.1
170
- return (
171
- version.major > 4 ||
172
- (version.major === 4 && version.minor > 5) ||
173
- (version.major === 4 && version.minor === 5 && version.patch >= 1)
174
- );
175
- }
176
- ```
177
-
178
- For older versions, wrap command with tee:
179
-
180
- ```javascript
181
- const wrappedCommand = `(${command}) 2>&1 | tee "${logFile}"`;
182
- const screenArgs = ['-dmS', sessionName, shell, shellArg, wrappedCommand];
183
- ```
184
-
185
- ## Testing Strategy
186
-
187
- 1. **Unit tests**: Test version detection logic
188
- 2. **Unit tests**: Test screen version comparison
189
- 3. **Integration tests**: Test output capture for both code paths
190
- 4. **Regression tests**: Verify existing tests still pass
191
- 5. **CI tests**: Ensure output is verified in assertions (not just exit code)
192
-
193
- ## References
194
-
195
- - [GNU Screen v.4.5.1 changelog](https://lists.gnu.org/archive/html/info-gnu/2017-02/msg00000.html) - Introduction of `-Logfile` option
196
- - [GitHub Issue: RHEL7 screen does not know the Logfile option](https://github.com/distributed-system-analysis/pbench/issues/1558)
197
- - [How to install GNU Screen on OS X using Homebrew](https://gist.github.com/bigeasy/2327150)
198
- - [GNU Screen Manual](https://www.gnu.org/software/screen/manual/screen.html)
199
- - [script command man page](https://man7.org/linux/man-pages/man1/script.1.html)
200
-
201
- ## Appendix: Test Logs
202
-
203
- See accompanying log files:
204
-
205
- - `test-output-1.log` - Initial reproduction
206
- - `screen-modes-test.log` - Screen modes investigation
207
- - `screen-attached-approaches.log` - Solution approaches testing
208
- - `test-screen-logfile.js` - Version compatibility testing