start-command 0.13.0 → 0.16.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/CHANGELOG.md +34 -227
- package/bun.lock +5 -0
- package/eslint.config.mjs +1 -1
- package/package.json +11 -6
- package/src/bin/cli.js +332 -171
- package/src/lib/args-parser.js +118 -0
- package/src/lib/execution-store.js +722 -0
- package/src/lib/isolation.js +51 -0
- package/src/lib/output-blocks.js +357 -0
- package/src/lib/status-formatter.js +148 -0
- package/src/lib/version.js +143 -0
- package/test/args-parser.test.js +107 -0
- package/test/cli.test.js +11 -1
- package/test/docker-autoremove.test.js +11 -16
- package/test/execution-store.test.js +483 -0
- package/test/isolation-cleanup.test.js +11 -16
- package/test/isolation.test.js +11 -17
- package/test/output-blocks.test.js +197 -0
- package/test/public-exports.test.js +105 -0
- package/test/status-query.test.js +197 -0
- package/.github/workflows/release.yml +0 -352
- package/.husky/pre-commit +0 -1
- package/ARCHITECTURE.md +0 -297
- package/LICENSE +0 -24
- package/README.md +0 -339
- package/REQUIREMENTS.md +0 -299
- package/docs/PIPES.md +0 -243
- package/docs/USAGE.md +0 -194
- package/docs/case-studies/issue-15/README.md +0 -208
- package/docs/case-studies/issue-18/README.md +0 -343
- package/docs/case-studies/issue-18/issue-comments.json +0 -1
- package/docs/case-studies/issue-18/issue-data.json +0 -7
- package/docs/case-studies/issue-22/analysis.md +0 -547
- package/docs/case-studies/issue-22/issue-data.json +0 -12
- package/docs/case-studies/issue-25/README.md +0 -232
- package/docs/case-studies/issue-25/issue-data.json +0 -21
- package/docs/case-studies/issue-28/README.md +0 -405
- package/docs/case-studies/issue-28/issue-data.json +0 -105
- package/docs/case-studies/issue-28/raw-issue-data.md +0 -92
- package/experiments/debug-regex.js +0 -49
- package/experiments/isolation-design.md +0 -131
- package/experiments/screen-output-test.js +0 -265
- package/experiments/test-cli.sh +0 -42
- package/experiments/test-command-stream-cjs.cjs +0 -30
- package/experiments/test-command-stream-wrapper.js +0 -54
- package/experiments/test-command-stream.mjs +0 -56
- package/experiments/test-screen-attached.js +0 -126
- package/experiments/test-screen-logfile.js +0 -286
- package/experiments/test-screen-modes.js +0 -128
- package/experiments/test-screen-output.sh +0 -27
- package/experiments/test-screen-tee-debug.js +0 -237
- package/experiments/test-screen-tee-fallback.js +0 -230
- package/experiments/test-substitution.js +0 -143
- package/experiments/user-isolation-research.md +0 -83
- package/scripts/changeset-version.mjs +0 -38
- package/scripts/check-file-size.mjs +0 -103
- package/scripts/create-github-release.mjs +0 -93
- package/scripts/create-manual-changeset.mjs +0 -89
- package/scripts/format-github-release.mjs +0 -83
- package/scripts/format-release-notes.mjs +0 -219
- package/scripts/instant-version-bump.mjs +0 -121
- package/scripts/publish-to-npm.mjs +0 -129
- package/scripts/setup-npm.mjs +0 -37
- package/scripts/validate-changeset.mjs +0 -107
- package/scripts/version-and-commit.mjs +0 -237
package/README.md
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
# start-command (`$`)
|
|
2
|
-
|
|
3
|
-
Gamification of coding - execute any command with automatic logging and ability to auto-report issues on GitHub.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
Install using [Bun](https://bun.sh):
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
bun install -g start-command
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
The `$` command acts as a wrapper for any shell command:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
$ ls -la
|
|
19
|
-
$ cat file.txt
|
|
20
|
-
$ npm test
|
|
21
|
-
$ git status
|
|
22
|
-
```
|
|
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
|
-
|
|
47
|
-
### Natural Language Commands (Aliases)
|
|
48
|
-
|
|
49
|
-
You can also use natural language to execute common commands. The `$` command supports pattern-based substitutions defined in `substitutions.lino`:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
# Install NPM packages
|
|
53
|
-
$ install lodash npm package # -> npm install lodash
|
|
54
|
-
$ install 4.17.21 version of lodash npm package # -> npm install lodash@4.17.21
|
|
55
|
-
$ install lodash npm package globally # -> npm install -g lodash
|
|
56
|
-
|
|
57
|
-
# Clone repositories
|
|
58
|
-
$ clone https://github.com/user/repo repository # -> git clone https://github.com/user/repo
|
|
59
|
-
|
|
60
|
-
# Git operations
|
|
61
|
-
$ checkout main branch # -> git checkout main
|
|
62
|
-
$ create feature-x branch # -> git checkout -b feature-x
|
|
63
|
-
|
|
64
|
-
# Common operations
|
|
65
|
-
$ list files # -> ls -la
|
|
66
|
-
$ show current directory # -> pwd
|
|
67
|
-
$ create my-project directory # -> mkdir -p my-project
|
|
68
|
-
|
|
69
|
-
# Python packages
|
|
70
|
-
$ install requests python package # -> pip install requests
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
If no pattern matches, the command is executed as-is.
|
|
74
|
-
|
|
75
|
-
## Features
|
|
76
|
-
|
|
77
|
-
### Natural Language Aliases (Links Notation)
|
|
78
|
-
|
|
79
|
-
Commands can be expressed in plain English using patterns defined in `substitutions.lino`. This file uses [Links Notation](https://github.com/link-foundation/links-notation) style patterns with variables.
|
|
80
|
-
|
|
81
|
-
Each pattern is defined as a doublet link - a pair of pattern and replacement wrapped in parentheses:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
# Pattern definition in substitutions.lino:
|
|
85
|
-
(
|
|
86
|
-
install $packageName npm package
|
|
87
|
-
npm install $packageName
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
# Usage:
|
|
91
|
-
$ install express npm package
|
|
92
|
-
# Executes: npm install express
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
Variables like `$packageName`, `$version`, `$repository` are captured and used in the substitution.
|
|
96
|
-
|
|
97
|
-
### Automatic Logging
|
|
98
|
-
|
|
99
|
-
All command output is automatically saved to your system's temporary directory with timestamps:
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
[2024-01-15 10:30:45.123] Starting: npm test
|
|
103
|
-
... command output ...
|
|
104
|
-
[2024-01-15 10:30:52.456] Finished
|
|
105
|
-
Exit code: 0
|
|
106
|
-
Log saved: /tmp/start-command-1705312245123-abc123.log
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Exit Code Display
|
|
110
|
-
|
|
111
|
-
The exit code is always prominently displayed after command completion, making it clear whether the command succeeded or failed.
|
|
112
|
-
|
|
113
|
-
### Auto-Reporting on Failure (NPM packages)
|
|
114
|
-
|
|
115
|
-
When a command fails (non-zero exit code) and it's a globally installed NPM package:
|
|
116
|
-
|
|
117
|
-
1. **Repository Detection** - Automatically detects the GitHub repository for NPM packages
|
|
118
|
-
2. **Log Upload** - Uploads the full log to GitHub (requires [gh-upload-log](https://github.com/link-foundation/gh-upload-log))
|
|
119
|
-
3. **Issue Creation** - Creates an issue in the package's repository with:
|
|
120
|
-
- Command that was executed
|
|
121
|
-
- Exit code
|
|
122
|
-
- System information
|
|
123
|
-
- Link to uploaded log
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
[2024-01-15 10:30:45.123] Starting: some-npm-tool --broken-arg
|
|
127
|
-
... error output ...
|
|
128
|
-
[2024-01-15 10:30:46.789] Finished
|
|
129
|
-
Exit code: 1
|
|
130
|
-
Log saved: /tmp/start-command-1705312246789-def456.log
|
|
131
|
-
|
|
132
|
-
Detected repository: https://github.com/owner/some-npm-tool
|
|
133
|
-
Log uploaded: https://gist.github.com/user/abc123
|
|
134
|
-
Issue created: https://github.com/owner/some-npm-tool/issues/42
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### Process Isolation
|
|
138
|
-
|
|
139
|
-
Run commands in isolated environments using terminal multiplexers, containers, or remote servers:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
# Run in tmux (attached by default)
|
|
143
|
-
$ --isolated tmux -- bun start
|
|
144
|
-
|
|
145
|
-
# Run in screen detached
|
|
146
|
-
$ --isolated screen --detached -- bun start
|
|
147
|
-
|
|
148
|
-
# Run in docker container
|
|
149
|
-
$ --isolated docker --image oven/bun:latest -- bun install
|
|
150
|
-
|
|
151
|
-
# Run on remote server via SSH
|
|
152
|
-
$ --isolated ssh --endpoint user@remote.server -- npm test
|
|
153
|
-
|
|
154
|
-
# Short form with custom session name
|
|
155
|
-
$ -i tmux -s my-session -d bun start
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### User Isolation
|
|
159
|
-
|
|
160
|
-
Create a new isolated user with the same group permissions as your current user to run commands in complete isolation:
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
# Create an isolated user with same permissions and run command
|
|
164
|
-
$ --isolated-user -- npm test
|
|
165
|
-
|
|
166
|
-
# Specify custom username for the isolated user
|
|
167
|
-
$ --isolated-user myrunner -- npm start
|
|
168
|
-
$ -u myrunner -- npm start
|
|
169
|
-
|
|
170
|
-
# Combine with process isolation (screen or tmux)
|
|
171
|
-
$ --isolated screen --isolated-user -- npm test
|
|
172
|
-
|
|
173
|
-
# Keep the user after command completes (don't delete)
|
|
174
|
-
$ --isolated-user --keep-user -- npm start
|
|
175
|
-
|
|
176
|
-
# The isolated user inherits your group memberships:
|
|
177
|
-
# - sudo group (if you have it)
|
|
178
|
-
# - docker group (if you have it)
|
|
179
|
-
# - wheel, admin, and other privileged groups
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
The `--isolated-user` option:
|
|
183
|
-
|
|
184
|
-
- Creates a new system user with the same group memberships as your current user
|
|
185
|
-
- Runs the command as that user
|
|
186
|
-
- Automatically deletes the user after the command completes (unless `--keep-user` is specified)
|
|
187
|
-
- Requires sudo access without password (NOPASSWD configuration)
|
|
188
|
-
- Works with screen and tmux isolation backends (not docker)
|
|
189
|
-
|
|
190
|
-
This is useful for:
|
|
191
|
-
|
|
192
|
-
- Running untrusted code in isolation
|
|
193
|
-
- Testing with a clean user environment
|
|
194
|
-
- Ensuring commands don't affect your user's files
|
|
195
|
-
|
|
196
|
-
#### Supported Backends
|
|
197
|
-
|
|
198
|
-
| Backend | Description | Installation |
|
|
199
|
-
| -------- | ---------------------------------------------- | ---------------------------------------------------------- |
|
|
200
|
-
| `screen` | GNU Screen terminal multiplexer | `apt install screen` / `brew install screen` |
|
|
201
|
-
| `tmux` | Modern terminal multiplexer | `apt install tmux` / `brew install tmux` |
|
|
202
|
-
| `docker` | Container isolation (requires --image) | [Docker Installation](https://docs.docker.com/get-docker/) |
|
|
203
|
-
| `ssh` | Remote execution via SSH (requires --endpoint) | `apt install openssh-client` / `brew install openssh` |
|
|
204
|
-
|
|
205
|
-
#### Isolation Options
|
|
206
|
-
|
|
207
|
-
| Option | Description |
|
|
208
|
-
| -------------------------------- | --------------------------------------------------------- |
|
|
209
|
-
| `--isolated, -i` | Isolation backend (screen, tmux, docker, ssh) |
|
|
210
|
-
| `--attached, -a` | Run in attached/foreground mode (default) |
|
|
211
|
-
| `--detached, -d` | Run in detached/background mode |
|
|
212
|
-
| `--session, -s` | Custom session/container name |
|
|
213
|
-
| `--image` | Docker image (required for docker isolation) |
|
|
214
|
-
| `--endpoint` | SSH endpoint (required for ssh, e.g., user@host) |
|
|
215
|
-
| `--isolated-user, -u [name]` | Create isolated user with same permissions (screen/tmux) |
|
|
216
|
-
| `--keep-user` | Keep isolated user after command completes (don't delete) |
|
|
217
|
-
| `--keep-alive, -k` | Keep session alive after command completes |
|
|
218
|
-
| `--auto-remove-docker-container` | Auto-remove docker container after exit (docker only) |
|
|
219
|
-
|
|
220
|
-
**Note:** Using both `--attached` and `--detached` together will result in an error - you must choose one mode.
|
|
221
|
-
|
|
222
|
-
#### Auto-Exit Behavior
|
|
223
|
-
|
|
224
|
-
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.
|
|
225
|
-
|
|
226
|
-
Use `--keep-alive` (`-k`) to keep the session running after command completion:
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
# Default: session exits after command completes
|
|
230
|
-
$ -i screen -d -- echo "hello"
|
|
231
|
-
# Session will exit automatically after command completes.
|
|
232
|
-
|
|
233
|
-
# With --keep-alive: session stays running for interaction
|
|
234
|
-
$ -i screen -d -k -- echo "hello"
|
|
235
|
-
# Session will stay alive after command completes.
|
|
236
|
-
# You can reattach with: screen -r <session-name>
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
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.
|
|
240
|
-
|
|
241
|
-
### Graceful Degradation
|
|
242
|
-
|
|
243
|
-
The tool works in any environment:
|
|
244
|
-
|
|
245
|
-
- **No `gh` CLI?** - Logs are still saved locally, auto-reporting is skipped
|
|
246
|
-
- **No `gh-upload-log`?** - Issue can still be created with local log reference
|
|
247
|
-
- **Repository not detected?** - Command runs normally with logging
|
|
248
|
-
- **No permission to create issue?** - Skipped with a clear message
|
|
249
|
-
- **Isolation backend not installed?** - Clear error message with installation instructions
|
|
250
|
-
|
|
251
|
-
## Requirements
|
|
252
|
-
|
|
253
|
-
### Required
|
|
254
|
-
|
|
255
|
-
- [Bun](https://bun.sh) >= 1.0.0
|
|
256
|
-
|
|
257
|
-
### Optional (for full auto-reporting)
|
|
258
|
-
|
|
259
|
-
- [GitHub CLI (`gh`)](https://cli.github.com/) - For authentication and issue creation
|
|
260
|
-
- [gh-upload-log](https://github.com/link-foundation/gh-upload-log) - For uploading log files
|
|
261
|
-
|
|
262
|
-
To set up auto-reporting:
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
# Install GitHub CLI and authenticate
|
|
266
|
-
gh auth login
|
|
267
|
-
|
|
268
|
-
# Install log uploader
|
|
269
|
-
bun install -g gh-upload-log
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## How It Works
|
|
273
|
-
|
|
274
|
-
1. **Command Execution** - Your command is passed directly to the shell (bash/powershell/sh)
|
|
275
|
-
2. **Output Capture** - Both stdout and stderr are captured while still being displayed
|
|
276
|
-
3. **Log File** - Complete output is saved with timestamps and system info
|
|
277
|
-
4. **Failure Handling** - On non-zero exit:
|
|
278
|
-
- Detects if the command is an NPM package
|
|
279
|
-
- Looks up the package's GitHub repository
|
|
280
|
-
- Uploads log (if `gh-upload-log` is available)
|
|
281
|
-
- Creates an issue (if `gh` is authenticated and has permission)
|
|
282
|
-
|
|
283
|
-
## Configuration
|
|
284
|
-
|
|
285
|
-
The following environment variables can be used to customize behavior:
|
|
286
|
-
|
|
287
|
-
| Variable | Description |
|
|
288
|
-
| ----------------------------- | -------------------------------------------------------------- |
|
|
289
|
-
| `START_DISABLE_AUTO_ISSUE` | Set to `1` or `true` to disable automatic issue creation |
|
|
290
|
-
| `START_DISABLE_LOG_UPLOAD` | Set to `1` or `true` to disable log upload |
|
|
291
|
-
| `START_LOG_DIR` | Custom directory for log files (defaults to OS temp directory) |
|
|
292
|
-
| `START_VERBOSE` | Set to `1` or `true` for verbose output |
|
|
293
|
-
| `START_DISABLE_SUBSTITUTIONS` | Set to `1` or `true` to disable pattern matching/aliases |
|
|
294
|
-
| `START_SUBSTITUTIONS_PATH` | Custom path to substitutions.lino file |
|
|
295
|
-
|
|
296
|
-
Example:
|
|
297
|
-
|
|
298
|
-
```bash
|
|
299
|
-
# Run without auto-issue creation
|
|
300
|
-
START_DISABLE_AUTO_ISSUE=1 $ bun test
|
|
301
|
-
|
|
302
|
-
# Use custom log directory
|
|
303
|
-
START_LOG_DIR=./logs $ bun test
|
|
304
|
-
|
|
305
|
-
# Disable substitutions (use raw command)
|
|
306
|
-
START_DISABLE_SUBSTITUTIONS=1 $ install lodash npm package
|
|
307
|
-
|
|
308
|
-
# Use custom substitutions file
|
|
309
|
-
START_SUBSTITUTIONS_PATH=/path/to/my-rules.lino $ install mypackage npm package
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Custom Substitutions
|
|
313
|
-
|
|
314
|
-
You can create your own substitution patterns by placing a `substitutions.lino` file in `~/.start-command/substitutions.lino`. User patterns take precedence over the default ones.
|
|
315
|
-
|
|
316
|
-
## Log File Format
|
|
317
|
-
|
|
318
|
-
Log files are saved as `start-command-{timestamp}-{random}.log` and contain:
|
|
319
|
-
|
|
320
|
-
```
|
|
321
|
-
=== Start Command Log ===
|
|
322
|
-
Timestamp: 2024-01-15 10:30:45.123
|
|
323
|
-
Command: bun test
|
|
324
|
-
Shell: /bin/bash
|
|
325
|
-
Platform: linux
|
|
326
|
-
Bun Version: 1.2.0
|
|
327
|
-
Working Directory: /home/user/project
|
|
328
|
-
==================================================
|
|
329
|
-
|
|
330
|
-
... command output ...
|
|
331
|
-
|
|
332
|
-
==================================================
|
|
333
|
-
Finished: 2024-01-15 10:30:52.456
|
|
334
|
-
Exit Code: 0
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
## License
|
|
338
|
-
|
|
339
|
-
MIT
|
package/REQUIREMENTS.md
DELETED
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
# Requirements for `$` Command (start-command)
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
The `$` command is a CLI tool that wraps any shell command and provides automatic logging, error reporting, issue creation capabilities, and natural language command aliases.
|
|
6
|
-
|
|
7
|
-
## Core Requirements
|
|
8
|
-
|
|
9
|
-
### 1. Command Proxy Functionality
|
|
10
|
-
|
|
11
|
-
- Act as a transparent proxy for any shell command
|
|
12
|
-
- Pass all arguments directly to the underlying shell (bash/powershell/sh)
|
|
13
|
-
- Support all standard commands: `$ ls`, `$ cat`, `$ mkdir`, etc.
|
|
14
|
-
- Preserve exit codes from wrapped commands
|
|
15
|
-
- Support natural language command aliases via pattern matching
|
|
16
|
-
|
|
17
|
-
### 2. Logging Requirements
|
|
18
|
-
|
|
19
|
-
#### 2.1 Log Storage
|
|
20
|
-
|
|
21
|
-
- Save full command output (stdout + stderr) to temporary OS directory
|
|
22
|
-
- Use platform-appropriate temp directory:
|
|
23
|
-
- Linux/macOS: `/tmp/` or `os.tmpdir()`
|
|
24
|
-
- Windows: `%TEMP%`
|
|
25
|
-
- Log file naming: `start-command-{timestamp}-{random}.log`
|
|
26
|
-
|
|
27
|
-
#### 2.2 Log Content
|
|
28
|
-
|
|
29
|
-
- Include timestamp at the start of logging
|
|
30
|
-
- Include timestamp at the end of logging
|
|
31
|
-
- Capture both stdout and stderr
|
|
32
|
-
- Store the complete command that was executed
|
|
33
|
-
- Store the exit code
|
|
34
|
-
|
|
35
|
-
#### 2.3 Log Display
|
|
36
|
-
|
|
37
|
-
- Print full log content to console after command finishes
|
|
38
|
-
- Always print the exit code (success or failure)
|
|
39
|
-
- Make exit code prominent as "it may usually be unclear"
|
|
40
|
-
|
|
41
|
-
### 3. Repository Detection
|
|
42
|
-
|
|
43
|
-
#### 3.1 NPM Package Detection
|
|
44
|
-
|
|
45
|
-
- Detect if the executed command is a globally installed NPM package
|
|
46
|
-
- Use `which` (Unix) or `where` (Windows) to find command location
|
|
47
|
-
- Check if command resolves to a path within npm global modules
|
|
48
|
-
- Extract package name from the path
|
|
49
|
-
- Use `npm view <package> repository.url` to get repository URL
|
|
50
|
-
|
|
51
|
-
#### 3.2 Supported Command Types
|
|
52
|
-
|
|
53
|
-
- Globally installed NPM packages (primary focus)
|
|
54
|
-
- Future: other package managers (pip, gem, etc.)
|
|
55
|
-
|
|
56
|
-
### 4. Automatic Issue Reporting (On Failure)
|
|
57
|
-
|
|
58
|
-
#### 4.1 Preconditions for Auto-Reporting
|
|
59
|
-
|
|
60
|
-
- Command must have failed (non-zero exit code)
|
|
61
|
-
- Repository must be detected for the command
|
|
62
|
-
- `gh` CLI tool must be authenticated
|
|
63
|
-
- User must have permission to create issues in target repository
|
|
64
|
-
|
|
65
|
-
#### 4.2 Log Upload
|
|
66
|
-
|
|
67
|
-
- Use `gh-upload-log` tool to upload the log file
|
|
68
|
-
- Upload as a gist (for logs ≤100MB)
|
|
69
|
-
- Print the uploaded log URL to console
|
|
70
|
-
|
|
71
|
-
#### 4.3 Issue Creation
|
|
72
|
-
|
|
73
|
-
- Create an issue in the detected repository
|
|
74
|
-
- Issue title: Include command name and error summary
|
|
75
|
-
- Issue body: Include:
|
|
76
|
-
- Command that was executed
|
|
77
|
-
- Exit code
|
|
78
|
-
- Link to uploaded log
|
|
79
|
-
- System information (OS, Bun/Node.js version)
|
|
80
|
-
- Timestamp
|
|
81
|
-
- Print the created issue URL to console
|
|
82
|
-
|
|
83
|
-
### 5. Graceful Degradation
|
|
84
|
-
|
|
85
|
-
#### 5.1 When Repository Cannot Be Detected
|
|
86
|
-
|
|
87
|
-
- Still log everything to temp directory
|
|
88
|
-
- Still print logs and exit code to console
|
|
89
|
-
- Skip log upload and issue creation
|
|
90
|
-
|
|
91
|
-
#### 5.2 When `gh` Is Not Authenticated
|
|
92
|
-
|
|
93
|
-
- Still log everything to temp directory
|
|
94
|
-
- Still print logs and exit code to console
|
|
95
|
-
- Print a message that auto-reporting is skipped
|
|
96
|
-
- Skip log upload and issue creation
|
|
97
|
-
|
|
98
|
-
#### 5.3 When `gh-upload-log` Is Not Installed
|
|
99
|
-
|
|
100
|
-
- Still log everything to temp directory
|
|
101
|
-
- Still print logs and exit code to console
|
|
102
|
-
- Print a message that log upload is skipped
|
|
103
|
-
- Skip issue creation (no log link available)
|
|
104
|
-
|
|
105
|
-
### 5. Command Aliases / Substitutions
|
|
106
|
-
|
|
107
|
-
#### 5.1 Pattern Matching
|
|
108
|
-
|
|
109
|
-
- Support natural language patterns defined in `substitutions.lino`
|
|
110
|
-
- Use Links Notation style with variables like `$packageName`, `$version`
|
|
111
|
-
- Match input against patterns and substitute with actual commands
|
|
112
|
-
- More specific patterns (more variables, longer patterns) take precedence
|
|
113
|
-
- Non-matching commands pass through unchanged
|
|
114
|
-
|
|
115
|
-
#### 5.2 Built-in Patterns
|
|
116
|
-
|
|
117
|
-
- NPM: `install $packageName npm package` -> `npm install $packageName`
|
|
118
|
-
- NPM with version: `install $version version of $packageName npm package` -> `npm install $packageName@$version`
|
|
119
|
-
- Git clone: `clone $repository repository` -> `git clone $repository`
|
|
120
|
-
- Git checkout: `checkout $branch branch` -> `git checkout $branch`
|
|
121
|
-
- Common operations: `list files` -> `ls -la`, `show current directory` -> `pwd`
|
|
122
|
-
|
|
123
|
-
#### 5.3 Custom Patterns
|
|
124
|
-
|
|
125
|
-
- Support user-defined patterns in `~/.start-command/substitutions.lino`
|
|
126
|
-
- User patterns take precedence over built-in patterns
|
|
127
|
-
- Support custom path via `START_SUBSTITUTIONS_PATH` environment variable
|
|
128
|
-
|
|
129
|
-
### 6. Process Isolation
|
|
130
|
-
|
|
131
|
-
#### 6.1 Command Syntax
|
|
132
|
-
|
|
133
|
-
Support two patterns for passing wrapper options:
|
|
134
|
-
|
|
135
|
-
- `$ [wrapper-options] -- [command] [command-options]` (explicit separator)
|
|
136
|
-
- `$ [wrapper-options] command [command-options]` (options before command)
|
|
137
|
-
|
|
138
|
-
#### 6.2 Isolation Options
|
|
139
|
-
|
|
140
|
-
- `--isolated, -i <backend>`: Run command in isolated environment
|
|
141
|
-
- `--attached, -a`: Run in attached/foreground mode (default)
|
|
142
|
-
- `--detached, -d`: Run in detached/background mode
|
|
143
|
-
- `--session, -s <name>`: Custom session name
|
|
144
|
-
- `--image <image>`: Docker image (required for docker backend)
|
|
145
|
-
- `--isolated-user, -u [username]`: Create new isolated user with same group permissions as current user
|
|
146
|
-
- `--keep-user`: Keep isolated user after command completes (don't delete)
|
|
147
|
-
- `--keep-alive, -k`: Keep isolation environment alive after command exits (disabled by default)
|
|
148
|
-
- `--auto-remove-docker-container`: Automatically remove docker container after exit (disabled by default, only valid with --isolated docker)
|
|
149
|
-
|
|
150
|
-
#### 6.3 Supported Backends
|
|
151
|
-
|
|
152
|
-
- `screen`: GNU Screen terminal multiplexer
|
|
153
|
-
- `tmux`: tmux terminal multiplexer
|
|
154
|
-
- `docker`: Docker containers (requires --image option)
|
|
155
|
-
|
|
156
|
-
#### 6.4 Mode Behavior
|
|
157
|
-
|
|
158
|
-
- **Attached mode**: Command runs in foreground, user can interact
|
|
159
|
-
- **Detached mode**: Command runs in background, session info displayed for reattachment
|
|
160
|
-
- **Conflict handling**: If both --attached and --detached are specified, show error asking user to choose one
|
|
161
|
-
|
|
162
|
-
#### 6.5 User Isolation
|
|
163
|
-
|
|
164
|
-
- `--isolated-user, -u [username]`: Create a new isolated user with same permissions
|
|
165
|
-
- Creates user with same group memberships as current user (sudo, docker, wheel, etc.)
|
|
166
|
-
- Automatically generates username if not specified
|
|
167
|
-
- User is automatically deleted after command completes (unless `--keep-user` is specified)
|
|
168
|
-
- For screen/tmux: Wraps command with `sudo -n -u <username>`
|
|
169
|
-
- Requires sudo NOPASSWD for useradd/userdel commands
|
|
170
|
-
- Works with screen and tmux isolation (not docker)
|
|
171
|
-
|
|
172
|
-
#### 6.6 Keep User Option
|
|
173
|
-
|
|
174
|
-
- `--keep-user`: Keep the isolated user after command completes
|
|
175
|
-
- Only valid with `--isolated-user` option
|
|
176
|
-
- User must be manually deleted later with `sudo userdel -r <username>`
|
|
177
|
-
|
|
178
|
-
Example usage:
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
# Create isolated user and run command (user auto-deleted after)
|
|
182
|
-
$ --isolated-user -- npm test
|
|
183
|
-
|
|
184
|
-
# Custom username for isolated user
|
|
185
|
-
$ --isolated-user myrunner -- npm start
|
|
186
|
-
$ -u myrunner -- npm start
|
|
187
|
-
|
|
188
|
-
# Combine with screen isolation
|
|
189
|
-
$ --isolated screen --isolated-user -- npm test
|
|
190
|
-
|
|
191
|
-
# Combine with tmux detached mode
|
|
192
|
-
$ -i tmux -d --isolated-user testuser -- npm run build
|
|
193
|
-
|
|
194
|
-
# Keep user after command completes
|
|
195
|
-
$ --isolated-user --keep-user -- npm test
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Benefits:
|
|
199
|
-
|
|
200
|
-
- Clean user environment for each run
|
|
201
|
-
- Inherits sudo/docker access from current user
|
|
202
|
-
- Files created during execution belong to isolated user
|
|
203
|
-
- Automatic cleanup after execution (unless --keep-user)
|
|
204
|
-
|
|
205
|
-
#### 6.7 Auto-Exit Behavior
|
|
206
|
-
|
|
207
|
-
By default, all isolation environments (screen, tmux, docker) automatically exit after the target command completes execution. This ensures:
|
|
208
|
-
|
|
209
|
-
- Resources are freed immediately after command execution
|
|
210
|
-
- No orphaned sessions/containers remain running
|
|
211
|
-
- Uniform behavior across all isolation backends
|
|
212
|
-
- Command output is still captured and logged before exit
|
|
213
|
-
|
|
214
|
-
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.
|
|
215
|
-
|
|
216
|
-
**Docker Container Filesystem Preservation:**
|
|
217
|
-
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.
|
|
218
|
-
|
|
219
|
-
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:
|
|
220
|
-
|
|
221
|
-
- The container is removed immediately after exiting (using docker's `--rm` flag)
|
|
222
|
-
- The container will not appear in `docker ps -a` after command completion
|
|
223
|
-
- You cannot re-enter the container to access files
|
|
224
|
-
- Resources are freed more aggressively
|
|
225
|
-
|
|
226
|
-
Note: `--auto-remove-docker-container` is only valid with `--isolated docker` and is independent of the `--keep-alive` flag.
|
|
227
|
-
|
|
228
|
-
#### 6.8 Graceful Degradation
|
|
229
|
-
|
|
230
|
-
- If isolation backend is not installed, show informative error with installation instructions
|
|
231
|
-
- If session creation fails, report error with details
|
|
232
|
-
- If sudo fails due to password requirement, command will fail with sudo error
|
|
233
|
-
|
|
234
|
-
## Configuration Options
|
|
235
|
-
|
|
236
|
-
- `START_DISABLE_AUTO_ISSUE`: Disable automatic issue creation
|
|
237
|
-
- `START_DISABLE_LOG_UPLOAD`: Disable log upload
|
|
238
|
-
- `START_LOG_DIR`: Custom log directory
|
|
239
|
-
- `START_VERBOSE`: Enable verbose output
|
|
240
|
-
- `START_DISABLE_SUBSTITUTIONS`: Disable pattern matching/aliases
|
|
241
|
-
- `START_SUBSTITUTIONS_PATH`: Custom path to substitutions file
|
|
242
|
-
|
|
243
|
-
## Output Format
|
|
244
|
-
|
|
245
|
-
### Success Case
|
|
246
|
-
|
|
247
|
-
```
|
|
248
|
-
[2024-01-15 10:30:45] Starting: ls -la
|
|
249
|
-
... command output ...
|
|
250
|
-
[2024-01-15 10:30:45] Finished
|
|
251
|
-
Exit code: 0
|
|
252
|
-
Log saved: /tmp/start-command-1705312245-abc123.log
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Failure Case (With Auto-Reporting)
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
[2024-01-15 10:30:45] Starting: failing-npm-command --arg
|
|
259
|
-
... command output/error ...
|
|
260
|
-
[2024-01-15 10:30:46] Finished
|
|
261
|
-
Exit code: 1
|
|
262
|
-
Log saved: /tmp/start-command-1705312246-def456.log
|
|
263
|
-
Detected repository: https://github.com/owner/repo
|
|
264
|
-
Log uploaded: https://gist.github.com/...
|
|
265
|
-
Issue created: https://github.com/owner/repo/issues/123
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Failure Case (Without Auto-Reporting)
|
|
269
|
-
|
|
270
|
-
```
|
|
271
|
-
[2024-01-15 10:30:45] Starting: unknown-command
|
|
272
|
-
... command output/error ...
|
|
273
|
-
[2024-01-15 10:30:45] Finished
|
|
274
|
-
Exit code: 127
|
|
275
|
-
Log saved: /tmp/start-command-1705312245-ghi789.log
|
|
276
|
-
Repository not detected - automatic issue creation skipped
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
## Dependencies
|
|
280
|
-
|
|
281
|
-
### Required
|
|
282
|
-
|
|
283
|
-
- **Bun >= 1.0.0** (primary runtime)
|
|
284
|
-
- `child_process` (built-in)
|
|
285
|
-
- `os` (built-in)
|
|
286
|
-
- `fs` (built-in)
|
|
287
|
-
- `path` (built-in)
|
|
288
|
-
|
|
289
|
-
### Optional (for full functionality)
|
|
290
|
-
|
|
291
|
-
- `gh` CLI - GitHub CLI for authentication and issue creation
|
|
292
|
-
- `gh-upload-log` - For uploading log files to GitHub
|
|
293
|
-
|
|
294
|
-
## Security Considerations
|
|
295
|
-
|
|
296
|
-
- Do not include sensitive environment variables in logs
|
|
297
|
-
- Do not include authentication tokens in issue reports
|
|
298
|
-
- Respect `.gitignore` patterns when detecting repositories
|
|
299
|
-
- Only create issues in public repositories unless explicitly authorized
|