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.
Files changed (65) hide show
  1. package/CHANGELOG.md +34 -227
  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 +332 -171
  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/output-blocks.js +357 -0
  10. package/src/lib/status-formatter.js +148 -0
  11. package/src/lib/version.js +143 -0
  12. package/test/args-parser.test.js +107 -0
  13. package/test/cli.test.js +11 -1
  14. package/test/docker-autoremove.test.js +11 -16
  15. package/test/execution-store.test.js +483 -0
  16. package/test/isolation-cleanup.test.js +11 -16
  17. package/test/isolation.test.js +11 -17
  18. package/test/output-blocks.test.js +197 -0
  19. package/test/public-exports.test.js +105 -0
  20. package/test/status-query.test.js +197 -0
  21. package/.github/workflows/release.yml +0 -352
  22. package/.husky/pre-commit +0 -1
  23. package/ARCHITECTURE.md +0 -297
  24. package/LICENSE +0 -24
  25. package/README.md +0 -339
  26. package/REQUIREMENTS.md +0 -299
  27. package/docs/PIPES.md +0 -243
  28. package/docs/USAGE.md +0 -194
  29. package/docs/case-studies/issue-15/README.md +0 -208
  30. package/docs/case-studies/issue-18/README.md +0 -343
  31. package/docs/case-studies/issue-18/issue-comments.json +0 -1
  32. package/docs/case-studies/issue-18/issue-data.json +0 -7
  33. package/docs/case-studies/issue-22/analysis.md +0 -547
  34. package/docs/case-studies/issue-22/issue-data.json +0 -12
  35. package/docs/case-studies/issue-25/README.md +0 -232
  36. package/docs/case-studies/issue-25/issue-data.json +0 -21
  37. package/docs/case-studies/issue-28/README.md +0 -405
  38. package/docs/case-studies/issue-28/issue-data.json +0 -105
  39. package/docs/case-studies/issue-28/raw-issue-data.md +0 -92
  40. package/experiments/debug-regex.js +0 -49
  41. package/experiments/isolation-design.md +0 -131
  42. package/experiments/screen-output-test.js +0 -265
  43. package/experiments/test-cli.sh +0 -42
  44. package/experiments/test-command-stream-cjs.cjs +0 -30
  45. package/experiments/test-command-stream-wrapper.js +0 -54
  46. package/experiments/test-command-stream.mjs +0 -56
  47. package/experiments/test-screen-attached.js +0 -126
  48. package/experiments/test-screen-logfile.js +0 -286
  49. package/experiments/test-screen-modes.js +0 -128
  50. package/experiments/test-screen-output.sh +0 -27
  51. package/experiments/test-screen-tee-debug.js +0 -237
  52. package/experiments/test-screen-tee-fallback.js +0 -230
  53. package/experiments/test-substitution.js +0 -143
  54. package/experiments/user-isolation-research.md +0 -83
  55. package/scripts/changeset-version.mjs +0 -38
  56. package/scripts/check-file-size.mjs +0 -103
  57. package/scripts/create-github-release.mjs +0 -93
  58. package/scripts/create-manual-changeset.mjs +0 -89
  59. package/scripts/format-github-release.mjs +0 -83
  60. package/scripts/format-release-notes.mjs +0 -219
  61. package/scripts/instant-version-bump.mjs +0 -121
  62. package/scripts/publish-to-npm.mjs +0 -129
  63. package/scripts/setup-npm.mjs +0 -37
  64. package/scripts/validate-changeset.mjs +0 -107
  65. package/scripts/version-and-commit.mjs +0 -237
@@ -1,352 +0,0 @@
1
- name: Checks and release
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- pull_request:
8
- types: [opened, synchronize, reopened]
9
- # Manual release support - consolidated here to work with npm trusted publishing
10
- # npm only allows ONE workflow file as trusted publisher, so all publishing
11
- # must go through this workflow (release.yml)
12
- workflow_dispatch:
13
- inputs:
14
- release_mode:
15
- description: 'Manual release mode'
16
- required: true
17
- type: choice
18
- default: 'instant'
19
- options:
20
- - instant
21
- - changeset-pr
22
- bump_type:
23
- description: 'Manual release type'
24
- required: true
25
- type: choice
26
- options:
27
- - patch
28
- - minor
29
- - major
30
- description:
31
- description: 'Manual release description (optional)'
32
- required: false
33
- type: string
34
-
35
- concurrency: ${{ github.workflow }}-${{ github.ref }}
36
-
37
- jobs:
38
- # Changeset check - only runs on PRs
39
- changeset-check:
40
- name: Check for Changesets
41
- runs-on: ubuntu-latest
42
- if: github.event_name == 'pull_request'
43
- steps:
44
- - uses: actions/checkout@v4
45
- with:
46
- fetch-depth: 0
47
-
48
- - name: Setup Bun
49
- uses: oven-sh/setup-bun@v2
50
- with:
51
- bun-version: latest
52
-
53
- - name: Install dependencies
54
- run: bun install
55
-
56
- - name: Check for changesets
57
- run: |
58
- # Skip changeset check for automated version PRs
59
- if [[ "${{ github.head_ref }}" == "changeset-release/"* ]]; then
60
- echo "Skipping changeset check for automated release PR"
61
- exit 0
62
- fi
63
-
64
- # Run changeset validation script
65
- bun scripts/validate-changeset.mjs
66
-
67
- # Linting and formatting - runs after changeset check on PRs, immediately on main
68
- lint:
69
- name: Lint and Format Check
70
- runs-on: ubuntu-latest
71
- needs: [changeset-check]
72
- if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success')
73
- steps:
74
- - uses: actions/checkout@v4
75
-
76
- - name: Setup Bun
77
- uses: oven-sh/setup-bun@v2
78
- with:
79
- bun-version: latest
80
-
81
- - name: Install dependencies
82
- run: bun install
83
-
84
- - name: Run ESLint
85
- run: bun run lint
86
-
87
- - name: Check formatting
88
- run: bun run format:check
89
-
90
- - name: Check file size limit
91
- run: bun scripts/check-file-size.mjs
92
-
93
- # Test with Bun only - 3 OS (Ubuntu, macOS, Windows)
94
- test:
95
- name: Test (Bun on ${{ matrix.os }})
96
- runs-on: ${{ matrix.os }}
97
- needs: [changeset-check]
98
- if: always() && (github.event_name == 'push' || needs.changeset-check.result == 'success')
99
- strategy:
100
- fail-fast: false
101
- matrix:
102
- os: [ubuntu-latest, macos-latest, windows-latest]
103
- steps:
104
- - uses: actions/checkout@v4
105
-
106
- - name: Setup Bun
107
- uses: oven-sh/setup-bun@v2
108
- with:
109
- bun-version: latest
110
-
111
- - name: Install screen (Linux)
112
- if: runner.os == 'Linux'
113
- run: sudo apt-get update && sudo apt-get install -y screen
114
-
115
- - name: Install screen (macOS)
116
- if: runner.os == 'macOS'
117
- run: brew install screen
118
-
119
- - name: Install dependencies
120
- run: bun install
121
-
122
- - name: Run tests
123
- run: bun test
124
-
125
- # Test both execution modes (default and command-stream)
126
- - name: Test default execution mode
127
- run: |
128
- bun run src/bin/cli.js echo "Testing default mode"
129
- echo "Default mode test passed"
130
-
131
- - name: Test command-stream execution mode
132
- run: |
133
- bun run src/bin/cli.js --use-command-stream echo "Testing command-stream mode"
134
- echo "Command-stream mode test passed"
135
-
136
- - name: Test command-stream via env variable
137
- env:
138
- START_USE_COMMAND_STREAM: '1'
139
- run: |
140
- bun run src/bin/cli.js echo "Testing env var mode"
141
- echo "Env var mode test passed"
142
-
143
- # SSH Integration Tests - Linux only (most reliable for SSH testing)
144
- - name: Setup SSH server for integration tests (Linux)
145
- if: runner.os == 'Linux'
146
- run: |
147
- # Install openssh-server if not present
148
- sudo apt-get install -y openssh-server
149
-
150
- # Start SSH service
151
- sudo systemctl start ssh
152
-
153
- # Generate SSH key without passphrase for testing
154
- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" -C "ci-test-key"
155
-
156
- # Add the public key to authorized_keys for passwordless login
157
- cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
158
- chmod 600 ~/.ssh/authorized_keys
159
-
160
- # Configure SSH to accept localhost connections without prompts
161
- mkdir -p ~/.ssh
162
- cat >> ~/.ssh/config << 'EOF'
163
- Host localhost
164
- StrictHostKeyChecking no
165
- UserKnownHostsFile /dev/null
166
- LogLevel ERROR
167
- EOF
168
- chmod 600 ~/.ssh/config
169
-
170
- # Test SSH connectivity
171
- ssh localhost "echo 'SSH connection successful'"
172
-
173
- - name: Run SSH integration tests (Linux)
174
- if: runner.os == 'Linux'
175
- run: bun test test/ssh-integration.test.js
176
-
177
- # Release - only runs on main after tests pass (for push events)
178
- release:
179
- name: Release
180
- needs: [lint, test]
181
- # Use always() to ensure this job runs even if changeset-check was skipped
182
- # This is needed because lint/test jobs have a transitive dependency on changeset-check
183
- if: always() && github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.lint.result == 'success' && needs.test.result == 'success'
184
- runs-on: ubuntu-latest
185
- # Permissions required for npm OIDC trusted publishing
186
- permissions:
187
- contents: write
188
- pull-requests: write
189
- id-token: write
190
- steps:
191
- - uses: actions/checkout@v4
192
- with:
193
- fetch-depth: 0
194
-
195
- - name: Setup Bun
196
- uses: oven-sh/setup-bun@v2
197
- with:
198
- bun-version: latest
199
-
200
- - name: Setup Node.js for npm publishing
201
- uses: actions/setup-node@v4
202
- with:
203
- node-version: '20.x'
204
- registry-url: 'https://registry.npmjs.org'
205
-
206
- - name: Install dependencies
207
- run: bun install
208
-
209
- - name: Update npm for OIDC trusted publishing
210
- run: bun scripts/setup-npm.mjs
211
-
212
- - name: Check for changesets
213
- id: check_changesets
214
- run: |
215
- # Count changeset files (excluding README.md and config.json)
216
- CHANGESET_COUNT=$(find .changeset -name "*.md" ! -name "README.md" | wc -l)
217
- echo "Found $CHANGESET_COUNT changeset file(s)"
218
- echo "has_changesets=$([[ $CHANGESET_COUNT -gt 0 ]] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
219
-
220
- - name: Version packages and commit to main
221
- if: steps.check_changesets.outputs.has_changesets == 'true'
222
- id: version
223
- run: bun scripts/version-and-commit.mjs --mode changeset
224
-
225
- - name: Publish to npm
226
- # Run if version was committed OR if a previous attempt already committed (for re-runs)
227
- if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
228
- id: publish
229
- run: bun scripts/publish-to-npm.mjs --should-pull
230
-
231
- - name: Create GitHub Release
232
- if: steps.publish.outputs.published == 'true'
233
- env:
234
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
235
- run: bun scripts/create-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}"
236
-
237
- - name: Format GitHub release notes
238
- if: steps.publish.outputs.published == 'true'
239
- env:
240
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
241
- run: bun scripts/format-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}" --commit-sha "${{ github.sha }}"
242
-
243
- # Manual Instant Release - triggered via workflow_dispatch with instant mode
244
- # This job is in release.yml because npm trusted publishing
245
- # only allows one workflow file to be registered as a trusted publisher
246
- instant-release:
247
- name: Instant Release
248
- if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'instant'
249
- runs-on: ubuntu-latest
250
- # Permissions required for npm OIDC trusted publishing
251
- permissions:
252
- contents: write
253
- pull-requests: write
254
- id-token: write
255
- steps:
256
- - uses: actions/checkout@v4
257
- with:
258
- fetch-depth: 0
259
-
260
- - name: Setup Bun
261
- uses: oven-sh/setup-bun@v2
262
- with:
263
- bun-version: latest
264
-
265
- - name: Setup Node.js for npm publishing
266
- uses: actions/setup-node@v4
267
- with:
268
- node-version: '20.x'
269
- registry-url: 'https://registry.npmjs.org'
270
-
271
- - name: Install dependencies
272
- run: bun install
273
-
274
- - name: Update npm for OIDC trusted publishing
275
- run: bun scripts/setup-npm.mjs
276
-
277
- - name: Version packages and commit to main
278
- id: version
279
- run: bun scripts/version-and-commit.mjs --mode instant --bump-type "${{ github.event.inputs.bump_type }}" --description "${{ github.event.inputs.description }}"
280
-
281
- - name: Publish to npm
282
- # Run if version was committed OR if a previous attempt already committed (for re-runs)
283
- if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
284
- id: publish
285
- run: bun scripts/publish-to-npm.mjs
286
-
287
- - name: Create GitHub Release
288
- if: steps.publish.outputs.published == 'true'
289
- env:
290
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
291
- run: bun scripts/create-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}"
292
-
293
- - name: Format GitHub release notes
294
- if: steps.publish.outputs.published == 'true'
295
- env:
296
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
297
- run: bun scripts/format-github-release.mjs --release-version "${{ steps.publish.outputs.published_version }}" --repository "${{ github.repository }}" --commit-sha "${{ github.sha }}"
298
-
299
- # Manual Changeset PR - creates a pull request with the changeset for review
300
- changeset-pr:
301
- name: Create Changeset PR
302
- if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'changeset-pr'
303
- runs-on: ubuntu-latest
304
- permissions:
305
- contents: write
306
- pull-requests: write
307
- steps:
308
- - uses: actions/checkout@v4
309
- with:
310
- fetch-depth: 0
311
-
312
- - name: Setup Bun
313
- uses: oven-sh/setup-bun@v2
314
- with:
315
- bun-version: latest
316
-
317
- - name: Install dependencies
318
- run: bun install
319
-
320
- - name: Create changeset file
321
- run: bun scripts/create-manual-changeset.mjs --bump-type "${{ github.event.inputs.bump_type }}" --description "${{ github.event.inputs.description }}"
322
-
323
- - name: Format changeset with Prettier
324
- run: |
325
- # Run Prettier on the changeset file to ensure it matches project style
326
- bun x prettier --write ".changeset/*.md" || true
327
-
328
- echo "Formatted changeset files"
329
-
330
- - name: Create Pull Request
331
- uses: peter-evans/create-pull-request@v7
332
- with:
333
- token: ${{ secrets.GITHUB_TOKEN }}
334
- commit-message: 'chore: add changeset for manual ${{ github.event.inputs.bump_type }} release'
335
- branch: changeset-manual-release-${{ github.run_id }}
336
- delete-branch: true
337
- title: 'chore: manual ${{ github.event.inputs.bump_type }} release'
338
- body: |
339
- ## Manual Release Request
340
-
341
- This PR was created by a manual workflow trigger to prepare a **${{ github.event.inputs.bump_type }}** release.
342
-
343
- ### Release Details
344
- - **Type:** ${{ github.event.inputs.bump_type }}
345
- - **Description:** ${{ github.event.inputs.description || 'Manual release' }}
346
- - **Triggered by:** @${{ github.actor }}
347
-
348
- ### Next Steps
349
- 1. Review the changeset in this PR
350
- 2. Merge this PR to main
351
- 3. The automated release workflow will create a version PR
352
- 4. Merge the version PR to publish to npm and create a GitHub release
package/.husky/pre-commit DELETED
@@ -1 +0,0 @@
1
- npx lint-staged
package/ARCHITECTURE.md DELETED
@@ -1,297 +0,0 @@
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/LICENSE DELETED
@@ -1,24 +0,0 @@
1
- This is free and unencumbered software released into the public domain.
2
-
3
- Anyone is free to copy, modify, publish, use, compile, sell, or
4
- distribute this software, either in source code form or as a compiled
5
- binary, for any purpose, commercial or non-commercial, and by any
6
- means.
7
-
8
- In jurisdictions that recognize copyright laws, the author or authors
9
- of this software dedicate any and all copyright interest in the
10
- software to the public domain. We make this dedication for the benefit
11
- of the public at large and to the detriment of our heirs and
12
- successors. We intend this dedication to be an overt act of
13
- relinquishment in perpetuity of all present and future rights to this
14
- software under copyright law.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- For more information, please refer to <https://unlicense.org>