turnout-cli 0.10.2 → 0.10.4

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 (2) hide show
  1. package/README.md +173 -171
  2. package/package.json +28 -28
package/README.md CHANGED
@@ -1,171 +1,173 @@
1
- <p align="center"><img src="https://github.com/lacodda/turnout/raw/main/assets/banner.svg" alt="turnout - a developer's switchyard" width="720"></p>
2
-
3
- > A developer's switchyard: point local apps at any backend stand, keep servers and secrets at hand, build and deploy - from any directory.
4
-
5
- <p align="center">
6
- <a href="https://crates.io/crates/turnout"><img src="https://img.shields.io/crates/v/turnout?style=flat-square" alt="crates.io"></a>
7
- <a href="https://www.npmjs.com/package/turnout-cli"><img src="https://img.shields.io/npm/v/turnout-cli?style=flat-square" alt="npm"></a>
8
- <a href="https://github.com/lacodda/turnout/actions"><img src="https://img.shields.io/github/actions/workflow/status/lacodda/turnout/ci.yml?style=flat-square" alt="CI"></a>
9
- <a href="https://github.com/lacodda/turnout/blob/main/LICENSE"><img src="https://img.shields.io/github/license/lacodda/turnout?style=flat-square" alt="License"></a>
10
- </p>
11
-
12
- ## Why
13
-
14
- Working against several backend stands scatters the day: you `cd` into a folder to start a project, edit `.env` files across repositories to switch a stand, dig through notes for a password, and keep deploy paths in your head.
15
-
16
- turnout keeps all of it in one place and works from any directory.
17
-
18
- ## A day in the life
19
-
20
- Point an app at a stand:
21
-
22
- ```console
23
- $ turnout use web staging
24
- 'web' now uses 'staging'.
25
- The running gateway picks this up automatically.
26
- Stand check: https://staging.example.com responded with 200 OK.
27
- ```
28
-
29
- Nothing in the project changed - the app still talks to `localhost`, and the [gateway](https://lacodda.github.io/turnout/concepts/gateway/) routes it to the stand you picked. Your session survives the switch, because cookies are kept per app **and** stand.
30
-
31
- Start working, from wherever you happen to be:
32
-
33
- ```console
34
- $ cd ~/dev/web/src/components
35
- $ turnout dev
36
- [web] pnpm dev
37
- ```
38
-
39
- Move the whole contour at once when the frontend and the API must agree:
40
-
41
- ```console
42
- $ turnout use contour prod-eu
43
- Group 'contour' now uses 'prod-eu':
44
- web -> prod-eu
45
- api -> prod-eu
46
- ```
47
-
48
- Forgot a name? Leave it out and pick from a list that shows where things point:
49
-
50
- ```console
51
- $ turnout use
52
- ? Switch ›
53
- ❯ contour group: web, api
54
- api -> staging
55
- web -> staging
56
- ```
57
-
58
- Ship it:
59
-
60
- ```console
61
- $ turnout deploy web -s prod-eu -b
62
- [web] pnpm build
63
- ✓ Connected to deploy@prod-eu.example.com:22
64
- ✓ Backup 20260809-011500.tar.gz created in /var/www/web.backups
65
- ================> 2.02 MiB/3.11 MiB · 1.81 MiB/s · eta 1s assets/index-b3f0a1.js
66
- Uploaded 142 files (3.11 MiB) to prod-eu:/var/www/web
67
- ✓ Ran: systemctl restart web
68
- Deploy of 'web' to 'prod-eu' finished.
69
- ```
70
-
71
- Every long flag has a short form, and nothing runs silently: the upload reports throughput and an ETA, and the steps that talk to the server say so while they wait.
72
-
73
- And see what has been going on:
74
-
75
- ```console
76
- $ turnout status
77
- turnout 0.10.2
78
- Data directory: ~/.local/share/lacodda/turnout
79
- Apps: 2 (api, web)
80
- Servers: 2 (prod-eu, staging)
81
- Group: contour (web, api)
82
- Creds: 1 (prod-deploy)
83
- Paths: 1 (wwwroot)
84
- Bindings:
85
- api -> staging
86
- web -> prod-eu
87
- Gateway: running (pid 24180; web:7100, api:7101)
88
- Recent:
89
- 2026-08-09T01:15:02Z deploy web -> prod-eu (142 files)
90
- 2026-08-09T01:12:44Z use web -> prod-eu
91
- ```
92
-
93
- ## What you get
94
-
95
- - **A dev gateway.** Apps always talk to `localhost`; turnout forwards to the selected stand over HTTP or HTTPS (self-signed certificates allowed per server), rewrites redirects, proxies WebSockets, and keeps a cookie jar per app+stand pair so switching does not log you out.
96
- - **Servers, logins and paths kept apart.** A machine, the credential that logs into it and the directory files land in are three named entities. Define a deploy account once and point every stand at it; declare a web root once and reuse it across servers.
97
- - **Secrets in the OS keyring** - Windows Credential Manager, macOS Keychain, Linux Secret Service. A secret belongs to a credential, so one `pass set` covers every stand that credential reaches. Copy it to the clipboard with one command; nothing lands in a config file, and `status` only ever reports *that* a credential exists.
98
- - **Commands from any directory.** `dev`, `build`, `test`, `lint` and any custom command run in the right project folder. Commands are taken from your actual `package.json` scripts, so a project whose dev script is `serve` still answers to `turnout dev`.
99
- - **Deploy over SSH/SFTP** - build, upload, restart, with remote backup and restore when a release goes wrong. Artifacts travel as a single archive instead of thousands of round trips, falling back to file-by-file when the server cannot unpack one. Linux and Windows servers alike: turnout detects which shell answers SSH and phrases every remote command in it.
100
- - **Portable settings.** `export` writes your apps, servers, credentials, paths and groups to one file and `import` merges it on another machine; secrets come along only when you ask, sealed with a passphrase.
101
- - **Stays current.** A once-a-day check mentions a new release without ever delaying a command, and `self-update` installs it - leaving package-manager installs to their package manager.
102
- - **Groups.** Bind a whole contour to one stand with a single `use`.
103
- - **Nothing to memorize.** Leave a name out and pick it from a list; in bash, Tab completes app, server, credential, path and group names from your own catalogs. The short alias `tn` is installed alongside.
104
- - **An action journal.** Every state change appends one JSON line - what happened and to which entities, never secrets or output. `tail`, `grep` and `jq` work on it directly.
105
-
106
- ## Install
107
-
108
- **One-line installers.** Windows (PowerShell):
109
-
110
- ```powershell
111
- irm https://raw.githubusercontent.com/lacodda/turnout/main/tools/install.ps1 | iex
112
- ```
113
-
114
- macOS / Linux:
115
-
116
- ```bash
117
- curl -fsSL https://raw.githubusercontent.com/lacodda/turnout/main/tools/install.sh | sh
118
- ```
119
-
120
- **With npm:**
121
-
122
- ```bash
123
- npm i -g turnout-cli
124
- ```
125
-
126
- **With cargo:**
127
-
128
- ```bash
129
- cargo install turnout
130
- ```
131
-
132
- **Binary releases** - grab the archive for your platform from [Releases](https://github.com/lacodda/turnout/releases/latest) (Windows x86_64, Linux x86_64, macOS arm64), unpack and put `turnout` on your `PATH`.
133
-
134
- The installers and the npm package also register the short alias `tn` (skipped if the name is already taken; `TURNOUT_NO_ALIAS=1` opts out). `cargo install` gives you `turnout` only.
135
-
136
- Both installers take the newest release by default; set `TURNOUT_VERSION` to a tag to pin one, and `TURNOUT_INSTALL_DIR` to choose where the binary lands.
137
-
138
- ## Quick start
139
-
140
- ```bash
141
- turnout setup # first-run wizard: creates the data directory
142
- turnout app add # register a project (detects its commands)
143
- turnout server add # register a stand
144
- turnout use # bind one to the other
145
- turnout gateway start # route traffic through the gateway
146
- turnout deploy-setup # to deploy: walks the credential and path too
147
- ```
148
-
149
- Data lives in the platform user data directory (e.g. `%LOCALAPPDATA%\lacodda\turnout` on Windows); set `TURNOUT_DATA_DIR` to override.
150
-
151
- Full command reference and concepts: **[lacodda.github.io/turnout](https://lacodda.github.io/turnout/)**.
152
-
153
- ## Status
154
-
155
- Everything above works today. What is next:
156
-
157
- - [ ] **Named builds** - app + server + credential + path under one name, so `turnout deploy webui-prod` works from any directory
158
- - [ ] **Key-based access, set up rather than only used** - generate a key, install it on the server and verify it in one command, including the Windows administrator case
159
- - [ ] **Background runs** - `dev --detach`, `ps`, `logs`, `stop`, OS notifications
160
- - [ ] **Observability** - gateway request log, `doctor`, `report` for handing context to an assistant
161
- - [ ] **Deploy consists** - atomic deploy and rollback across a group of apps
162
-
163
- Released versions and what landed in each: [CHANGELOG on the Releases page](https://github.com/lacodda/turnout/releases).
164
-
165
- ## Documentation
166
-
167
- The documentation site (Astro Starlight) lives in [`docs/`](https://github.com/lacodda/turnout/tree/main/docs); architecture decision records are in [`docs/adr/`](https://github.com/lacodda/turnout/tree/main/docs/adr).
168
-
169
- ## License
170
-
171
- MIT (c) [Kirill Lakhtachev](https://lacodda.com)
1
+ <p align="center"><img src="https://github.com/lacodda/turnout/raw/main/assets/banner.svg" alt="turnout - a developer's switchyard" width="720"></p>
2
+
3
+ > A developer's switchyard: point local apps at any backend stand, keep servers and secrets at hand, build and deploy - from any directory.
4
+
5
+ <p align="center">
6
+ <a href="https://crates.io/crates/turnout"><img src="https://img.shields.io/crates/v/turnout?style=flat-square" alt="crates.io"></a>
7
+ <a href="https://www.npmjs.com/package/turnout-cli"><img src="https://img.shields.io/npm/v/turnout-cli?style=flat-square" alt="npm"></a>
8
+ <a href="https://github.com/lacodda/turnout/actions"><img src="https://img.shields.io/github/actions/workflow/status/lacodda/turnout/ci.yml?style=flat-square" alt="CI"></a>
9
+ <a href="https://github.com/lacodda/turnout/blob/main/LICENSE"><img src="https://img.shields.io/github/license/lacodda/turnout?style=flat-square" alt="License"></a>
10
+ </p>
11
+
12
+ ## Why
13
+
14
+ Working against several backend stands scatters the day: you `cd` into a folder to start a project, edit `.env` files across repositories to switch a stand, dig through notes for a password, and keep deploy paths in your head.
15
+
16
+ turnout keeps all of it in one place and works from any directory.
17
+
18
+ ## A day in the life
19
+
20
+ Point an app at a stand:
21
+
22
+ ```console
23
+ $ turnout use web staging
24
+ 'web' now uses 'staging'.
25
+ The running gateway picks this up automatically.
26
+ Stand check: https://staging.example.com responded with 200 OK.
27
+ ```
28
+
29
+ Nothing in the project changed - the app still talks to `localhost`, and the [gateway](https://lacodda.github.io/turnout/concepts/gateway/) routes it to the stand you picked. Your session survives the switch, because cookies are kept per app **and** stand.
30
+
31
+ Start working, from wherever you happen to be:
32
+
33
+ ```console
34
+ $ cd ~/dev/web/src/components
35
+ $ turnout dev
36
+ [web] pnpm dev
37
+ ```
38
+
39
+ Move the whole contour at once when the frontend and the API must agree:
40
+
41
+ ```console
42
+ $ turnout use contour prod-eu
43
+ Group 'contour' now uses 'prod-eu':
44
+ web -> prod-eu
45
+ api -> prod-eu
46
+ ```
47
+
48
+ Forgot a name? Leave it out and pick from a list that shows where things point:
49
+
50
+ ```console
51
+ $ turnout use
52
+ ? Switch ›
53
+ ❯ contour group: web, api
54
+ api -> staging
55
+ web -> staging
56
+ ```
57
+
58
+ Ship it:
59
+
60
+ ```console
61
+ $ turnout deploy web -s prod-eu -b
62
+ [web] pnpm build
63
+ ✓ Connected to deploy@prod-eu.example.com:22
64
+ ✓ Backup 20260809-011500.tar.gz created in /var/www/web.backups
65
+ ================> 2.02 MiB/3.11 MiB · 1.81 MiB/s · eta 1s assets/index-b3f0a1.js
66
+ Uploaded 142 files (3.11 MiB) to prod-eu:/var/www/web
67
+ ✓ Ran: systemctl restart web
68
+ Deploy of 'web' to 'prod-eu' finished.
69
+ ```
70
+
71
+ Every long flag has a short form, and nothing runs silently: the upload reports throughput and an ETA, and the steps that talk to the server say so while they wait.
72
+
73
+ And see what has been going on:
74
+
75
+ ```console
76
+ $ turnout status
77
+ turnout 0.10.4
78
+ Data directory: ~/.local/share/lacodda/turnout
79
+ Apps: 2 (api, web)
80
+ Servers: 2 (prod-eu, staging)
81
+ Group: contour (web, api)
82
+ Creds: 1 (prod-deploy)
83
+ Paths: 1 (wwwroot)
84
+ Bindings:
85
+ api -> staging
86
+ web -> prod-eu
87
+ Gateway: running (pid 24180; web:7100, api:7101)
88
+ Recent:
89
+ 2026-08-09T01:15:02Z deploy web -> prod-eu (142 files)
90
+ 2026-08-09T01:12:44Z use web -> prod-eu
91
+ ```
92
+
93
+ ## What you get
94
+
95
+ - **A dev gateway.** Apps always talk to `localhost`; turnout forwards to the selected stand over HTTP or HTTPS (self-signed certificates allowed per server), rewrites redirects, proxies WebSockets, and keeps a cookie jar per app+stand pair so switching does not log you out.
96
+ - **Servers, logins and paths kept apart.** A machine, the credential that logs into it and the directory files land in are three named entities. Define a deploy account once and point every stand at it; declare a web root once and reuse it across servers.
97
+ - **Secrets in the OS keyring** - Windows Credential Manager, macOS Keychain, Linux Secret Service. A secret belongs to a credential, so one `pass set` covers every stand that credential reaches. Copy it to the clipboard with one command; nothing lands in a config file, and `status` only ever reports *that* a credential exists.
98
+ - **Commands from any directory.** `dev`, `build`, `test`, `lint` and any custom command run in the right project folder. Commands are taken from your actual `package.json` scripts, so a project whose dev script is `serve` still answers to `turnout dev`.
99
+ - **Deploy over SSH/SFTP** - build, upload, restart, with remote backup and restore when a release goes wrong. Artifacts travel as a single archive instead of thousands of round trips, falling back to file-by-file when the server cannot unpack one. Linux and Windows servers alike: turnout detects which shell answers SSH and phrases every remote command in it.
100
+ - **Portable settings.** `export` writes your apps, servers, credentials, paths and groups to one file and `import` merges it on another machine; secrets come along only when you ask, sealed with a passphrase.
101
+ - **Stays current.** A once-a-day check mentions a new release without ever delaying a command, and `self-update` installs it - leaving package-manager installs to their package manager.
102
+ - **Groups.** Bind a whole contour to one stand with a single `use`.
103
+ - **Nothing to memorize.** Leave a name out and pick it from a list; in bash, Tab completes app, server, credential, path and group names from your own catalogs. The short alias `tn` is installed alongside.
104
+ - **An action journal.** Every state change appends one JSON line - what happened and to which entities, never secrets or output. `tail`, `grep` and `jq` work on it directly.
105
+
106
+ ## Install
107
+
108
+ **One-line installers.** Windows (PowerShell):
109
+
110
+ ```powershell
111
+ irm https://raw.githubusercontent.com/lacodda/turnout/main/tools/install.ps1 | iex
112
+ ```
113
+
114
+ macOS / Linux:
115
+
116
+ ```bash
117
+ curl -fsSL https://raw.githubusercontent.com/lacodda/turnout/main/tools/install.sh | sh
118
+ ```
119
+
120
+ On Windows use the PowerShell line above: `install.sh` carries the macOS and Linux builds only, and run from Git Bash it stops with a pointer back here.
121
+
122
+ **With npm:**
123
+
124
+ ```bash
125
+ npm i -g turnout-cli
126
+ ```
127
+
128
+ **With cargo:**
129
+
130
+ ```bash
131
+ cargo install turnout
132
+ ```
133
+
134
+ **Binary releases** - grab the archive for your platform from [Releases](https://github.com/lacodda/turnout/releases/latest) (Windows x86_64, Linux x86_64, macOS arm64), unpack and put `turnout` on your `PATH`.
135
+
136
+ The installers and the npm package also register the short alias `tn` (skipped if the name is already taken; `TURNOUT_NO_ALIAS=1` opts out). `cargo install` gives you `turnout` only. The alias is a link to the binary rather than a copy of it, so an install costs one binary and both names always answer with the same version.
137
+
138
+ Both installers take the newest release by default; set `TURNOUT_VERSION` to a tag to pin one, and `TURNOUT_INSTALL_DIR` to choose where the binary lands.
139
+
140
+ ## Quick start
141
+
142
+ ```bash
143
+ turnout setup # first-run wizard: creates the data directory
144
+ turnout app add # register a project (detects its commands)
145
+ turnout server add # register a stand
146
+ turnout use # bind one to the other
147
+ turnout gateway start # route traffic through the gateway
148
+ turnout deploy-setup # to deploy: walks the credential and path too
149
+ ```
150
+
151
+ Data lives in the platform user data directory (e.g. `%LOCALAPPDATA%\lacodda\turnout` on Windows); set `TURNOUT_DATA_DIR` to override.
152
+
153
+ Full command reference and concepts: **[lacodda.github.io/turnout](https://lacodda.github.io/turnout/)**.
154
+
155
+ ## Status
156
+
157
+ Everything above works today. What is next:
158
+
159
+ - [ ] **Named builds** - app + server + credential + path under one name, so `turnout deploy webui-prod` works from any directory
160
+ - [ ] **Key-based access, set up rather than only used** - generate a key, install it on the server and verify it in one command, including the Windows administrator case
161
+ - [ ] **Background runs** - `dev --detach`, `ps`, `logs`, `stop`, OS notifications
162
+ - [ ] **Observability** - gateway request log, `doctor`, `report` for handing context to an assistant
163
+ - [ ] **Deploy consists** - atomic deploy and rollback across a group of apps
164
+
165
+ Released versions and what landed in each: [CHANGELOG on the Releases page](https://github.com/lacodda/turnout/releases).
166
+
167
+ ## Documentation
168
+
169
+ The documentation site (Astro Starlight) lives in [`docs/`](https://github.com/lacodda/turnout/tree/main/docs); architecture decision records are in [`docs/adr/`](https://github.com/lacodda/turnout/tree/main/docs/adr).
170
+
171
+ ## License
172
+
173
+ MIT (c) [Kirill Lakhtachev](https://lacodda.com)
package/package.json CHANGED
@@ -1,28 +1,28 @@
1
- {
2
- "name": "turnout-cli",
3
- "version": "0.10.2",
4
- "turnout": {
5
- "binary": "v0.10.2"
6
- },
7
- "description": "A developer's switchyard: point local apps at any backend stand, keep servers and secrets at hand, build and deploy from any directory",
8
- "license": "MIT",
9
- "author": "Kirill Lakhtachev <lahtachev@gmail.com> (https://lacodda.com)",
10
- "homepage": "https://lacodda.github.io/turnout/",
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/lacodda/turnout.git"
14
- },
15
- "keywords": ["cli", "proxy", "gateway", "deploy", "dev-environment", "stands"],
16
- "bin": {
17
- "turnout": "run.js",
18
- "tn": "run.js"
19
- },
20
- "files": ["download.js", "install.js", "run.js"],
21
- "scripts": {
22
- "postinstall": "node install.js"
23
- },
24
- "os": ["win32", "darwin", "linux"],
25
- "engines": {
26
- "node": ">=18"
27
- }
28
- }
1
+ {
2
+ "name": "turnout-cli",
3
+ "version": "0.10.4",
4
+ "turnout": {
5
+ "binary": "v0.10.4"
6
+ },
7
+ "description": "A developer's switchyard: point local apps at any backend stand, keep servers and secrets at hand, build and deploy from any directory",
8
+ "license": "MIT",
9
+ "author": "Kirill Lakhtachev <lahtachev@gmail.com> (https://lacodda.com)",
10
+ "homepage": "https://lacodda.github.io/turnout/",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/lacodda/turnout.git"
14
+ },
15
+ "keywords": ["cli", "proxy", "gateway", "deploy", "dev-environment", "stands"],
16
+ "bin": {
17
+ "turnout": "run.js",
18
+ "tn": "run.js"
19
+ },
20
+ "files": ["download.js", "install.js", "run.js"],
21
+ "scripts": {
22
+ "postinstall": "node install.js"
23
+ },
24
+ "os": ["win32", "darwin", "linux"],
25
+ "engines": {
26
+ "node": ">=18"
27
+ }
28
+ }