msdev 0.12.0__tar.gz → 0.13.0__tar.gz
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.
- {msdev-0.12.0 → msdev-0.13.0}/PKG-INFO +77 -33
- {msdev-0.12.0 → msdev-0.13.0}/README.md +76 -32
- {msdev-0.12.0 → msdev-0.13.0}/pyproject.toml +6 -2
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/__init__.py +1 -1
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/cli.py +378 -67
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/compat.py +6 -6
- msdev-0.13.0/src/msdev/core/config_bundle.py +338 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/env_transfer.py +30 -29
- msdev-0.13.0/src/msdev/core/exec_argv.py +196 -0
- msdev-0.13.0/src/msdev/core/init_setup.py +42 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/node.py +117 -3
- msdev-0.13.0/src/msdev/core/sftp_transfer.py +120 -0
- msdev-0.13.0/src/msdev/core/skill_install.py +258 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/ssh_auth.py +72 -82
- msdev-0.13.0/src/msdev/core/ssh_config.py +380 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/ssh_tunnel.py +5 -2
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/stream_transport.py +9 -3
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/transport.py +84 -48
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/helpers/msdevd-linux-amd64 +0 -0
- msdev-0.13.0/src/msdev/helpers/msdevd-linux-amd64.sha256 +1 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/helpers/msdevd-linux-arm64 +0 -0
- msdev-0.13.0/src/msdev/helpers/msdevd-linux-arm64.sha256 +1 -0
- msdev-0.13.0/src/msdev/skills/msdev-cli/SKILL.md +182 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev.egg-info/PKG-INFO +77 -33
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev.egg-info/SOURCES.txt +14 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_cli.py +41 -33
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_cli_only_architecture.py +11 -4
- msdev-0.13.0/tests/test_config_bundle.py +224 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_daemon_deploy.py +16 -11
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_env_transfer.py +16 -11
- msdev-0.13.0/tests/test_exec_argv.py +133 -0
- msdev-0.13.0/tests/test_exec_command_scenario.py +152 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_exec_default_timeout_scenario.py +2 -8
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_go_msdevd_scenario.py +1 -1
- msdev-0.13.0/tests/test_init_skill.py +241 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_msdev_cli_skill.py +20 -3
- msdev-0.13.0/tests/test_node_connect_provision_scenario.py +104 -0
- msdev-0.13.0/tests/test_node_connect_save_password_scenario.py +87 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_node_env_services.py +17 -8
- msdev-0.13.0/tests/test_node_sync_ssh_scenario.py +76 -0
- msdev-0.13.0/tests/test_sftp_transfer_scenario.py +109 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_ssh_auth.py +75 -58
- msdev-0.13.0/tests/test_ssh_config.py +171 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_transport.py +54 -31
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_windows_local_scenario.py +12 -17
- msdev-0.12.0/src/msdev/core/exec_argv.py +0 -82
- msdev-0.12.0/src/msdev/helpers/msdevd-linux-amd64.sha256 +0 -1
- msdev-0.12.0/src/msdev/helpers/msdevd-linux-arm64.sha256 +0 -1
- msdev-0.12.0/tests/test_exec_argv.py +0 -55
- {msdev-0.12.0 → msdev-0.13.0}/LICENSE +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/setup.cfg +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/__init__.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/config.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/container_helper.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/daemon_deploy.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/guides.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/helper_deploy.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/host_files.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/host_mutations.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/inventory.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/limits.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/local_rpc.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/multiplex.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/request_client.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/resources.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/__init__.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/capabilities.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/context.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/environment.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/execution.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/model.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/npu.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/services/results.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/stream_limits.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/stream_server.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/core/streamproto.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/daemon.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/helpers/msdev-file-helper-linux-amd64 +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/helpers/msdev-file-helper-linux-amd64.sha256 +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/helpers/msdev-file-helper-linux-arm64 +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev/helpers/msdev-file-helper-linux-arm64.sha256 +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev.egg-info/dependency_links.txt +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev.egg-info/entry_points.txt +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/src/msdev.egg-info/top_level.txt +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_compat.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_config.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_connect_env_scenario.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_container_helper.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_daemon.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_daemon_container_stream.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_docker_stream_dispatch.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_env_put_get_scenario.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_env_read_write_scenario.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_helper_deploy.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_inventory.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_model_cli.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_model_services.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_multiplex.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_node_env_config.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_request_client.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_ssh_tunnel.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_stream_server.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_stream_transport.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_streamproto.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_target_exec_services.py +0 -0
- {msdev-0.12.0 → msdev-0.13.0}/tests/test_target_guides.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: msdev
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: Portable nodes and execution environments for msModelSlim development
|
|
5
5
|
Author: msModelSlim Agent Contributors
|
|
6
6
|
License-Expression: MulanPSL-2.0
|
|
@@ -32,7 +32,8 @@ A Node owns SSH reachability and `msdevd` deployment. An Env owns the full
|
|
|
32
32
|
execution context: host or Docker runtime, conda/venv/uv layers, optional
|
|
33
33
|
`setup` script (root switch, proxy, etc.), command `wrap`, and static env vars.
|
|
34
34
|
|
|
35
|
-
The CLI is intentionally stateless: execution always names
|
|
35
|
+
The CLI is intentionally stateless: execution always names the env as the first
|
|
36
|
+
`exec` argument.
|
|
36
37
|
MCP is not part of the architecture.
|
|
37
38
|
|
|
38
39
|
## Install
|
|
@@ -46,6 +47,20 @@ msdev --help
|
|
|
46
47
|
|
|
47
48
|
The package installs `msdev` and `msdevd`.
|
|
48
49
|
|
|
50
|
+
Install the agent skill for Cursor and Claude Code, and sync SSH config:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
msdev init
|
|
54
|
+
msdev init --scope project
|
|
55
|
+
msdev init -f
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`init` registers Host aliases from `~/.ssh/config`, prints added/removed
|
|
59
|
+
changes, and writes `skills/msdev-cli/SKILL.md` into `~/.cursor/skills/` and
|
|
60
|
+
`~/.claude/skills/` (or into `.cursor/` / `.claude/` under the current
|
|
61
|
+
directory with `--scope project`). Outdated skill files prompt before
|
|
62
|
+
overwrite; use `-f` to force.
|
|
63
|
+
|
|
49
64
|
## Windows client
|
|
50
65
|
|
|
51
66
|
The typical setup is a **Windows laptop talking to Linux Nodes** via OpenSSH
|
|
@@ -58,13 +73,13 @@ implement ControlMaster multiplexing, so msdev:
|
|
|
58
73
|
RPC (same role as ControlMaster). Explicit `msdev node connect NODE` is
|
|
59
74
|
optional; disable persist with `MSDEV_SSH_LOCAL_FORWARD_PERSIST=0`;
|
|
60
75
|
- reuses that tunnel for captured RPC and default streaming `msdev exec`;
|
|
61
|
-
`env put`/`get` stay on
|
|
76
|
+
`env put`/`get` stay on sftp/ssh streams (file bytes do not go through JSON RPC);
|
|
62
77
|
- hides SSH console windows (`CREATE_NO_WINDOW`) and kills process trees with
|
|
63
78
|
`taskkill /T` on timeout or cancel;
|
|
64
79
|
- SSH is non-interactive: `BatchMode` unless a password is supplied, host keys
|
|
65
80
|
use `accept-new`, and there is no password/passphrase/yes-no prompt. When a
|
|
66
81
|
password is known, injects OpenSSH `SSH_ASKPASS` so `node connect` (and later
|
|
67
|
-
ssh/
|
|
82
|
+
ssh/sftp) can authenticate without a TTY; the local public key is then
|
|
68
83
|
installed on the Node so later logins are passwordless. The password is
|
|
69
84
|
never written to the node registry;
|
|
70
85
|
- serves a TCP loopback endpoint for local `msdevd` when this Python build has
|
|
@@ -82,22 +97,25 @@ If `ssh` is not on PATH, msdev looks in `%SystemRoot%\System32\OpenSSH\`.
|
|
|
82
97
|
|
|
83
98
|
## Nodes and execution environments
|
|
84
99
|
|
|
85
|
-
|
|
100
|
+
Use **`node connect`** as the single entry point: it writes `~/.ssh/config`
|
|
101
|
+
when needed, registers the node, saves passwords, installs the local public
|
|
102
|
+
key, and deploys `msdevd`:
|
|
86
103
|
|
|
87
104
|
```bash
|
|
88
|
-
msdev node
|
|
105
|
+
msdev node connect dev-122 --hostname 80.48.33.133 --user root --password PASSWORD
|
|
106
|
+
msdev node connect dev-122
|
|
107
|
+
msdev node sync-ssh
|
|
108
|
+
msdev node list --ssh
|
|
89
109
|
msdev node list
|
|
90
|
-
msdev node status dev-122
|
|
91
110
|
```
|
|
92
111
|
|
|
93
|
-
|
|
94
|
-
|
|
112
|
+
Connect writes or updates a dedicated `Host <name>` block in OpenSSH config.
|
|
113
|
+
The msdev registry stores only the Host alias plus msdevd settings
|
|
114
|
+
(`remote_bin`, `auto_bootstrap`). User, port, keys, and proxy remain in SSH
|
|
115
|
+
config. `node sync-ssh` registers Host aliases that were added manually.
|
|
95
116
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Connect uploads a **static Go msdevd** binary matching the node architecture
|
|
117
|
+
Connect atomically creates a same-named host Env on first use and uploads a
|
|
118
|
+
**static Go msdevd** binary matching the node architecture
|
|
101
119
|
(`linux-amd64` / `linux-arm64`) when the agent is missing or stale. No Python
|
|
102
120
|
is required on the node.
|
|
103
121
|
|
|
@@ -113,19 +131,14 @@ The Go source is in `msdev/`.
|
|
|
113
131
|
|
|
114
132
|
Persistent OpenSSH masters are optional. All SSH from msdev is
|
|
115
133
|
non-interactive: host keys use `accept-new`, and password/passphrase prompts
|
|
116
|
-
are disabled. Supply
|
|
117
|
-
|
|
118
|
-
if missing) so later connections
|
|
134
|
+
are disabled. Supply `--password` on connect; it is saved to ``~/.ssh/config``
|
|
135
|
+
as ``# msdev Password ...`` and used to install the local public key
|
|
136
|
+
(``~/.ssh/id_ed25519``, generated if missing) so later connections can be
|
|
137
|
+
passwordless:
|
|
119
138
|
|
|
120
139
|
```bash
|
|
121
|
-
|
|
122
|
-
export MSDEV_SSH_PASSWORD='...'
|
|
123
|
-
export MSDEV_SSH_PASSWORD_DEV_122='...' # per-node override
|
|
124
|
-
|
|
140
|
+
msdev node connect dev-122 --hostname 80.48.33.133 --user root --password PASSWORD
|
|
125
141
|
msdev node connect dev-122
|
|
126
|
-
msdev node connect dev-122 --password-file FILE
|
|
127
|
-
msdev node connect dev-122 --password-env VAR
|
|
128
|
-
msdev node connect dev-122 --password PASSWORD # non-interactive; visible in ps
|
|
129
142
|
msdev node connect dev-122 --identity FILE # choose which key to install
|
|
130
143
|
msdev node connect dev-122 --no-install-key # password only, do not copy key
|
|
131
144
|
msdev node disconnect dev-122
|
|
@@ -144,6 +157,17 @@ Guides are stored under `~/.config/msdev/guides/nodes/` and
|
|
|
144
157
|
`~/.config/msdev/guides/environments/`. **Node guides** document how to
|
|
145
158
|
connect; **Env guides** document how to initialize shared context (`setup`).
|
|
146
159
|
|
|
160
|
+
Share a full local configuration (registry + guides) with:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
msdev config export ./msdev-config.tar.gz
|
|
164
|
+
msdev config import ./msdev-config.tar.gz
|
|
165
|
+
msdev config import ./msdev-config.tar.gz --force # overwrite name conflicts
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Bundles contain `resources.json`, both guide trees, and a `manifest.json`.
|
|
169
|
+
SSH keys and passwords are never exported.
|
|
170
|
+
|
|
147
171
|
```bash
|
|
148
172
|
msdev env add dev-122-root \
|
|
149
173
|
--node dev-122 \
|
|
@@ -173,7 +197,7 @@ msdev env get dev-122 /srv/project/config.yaml > ./config.yaml
|
|
|
173
197
|
```
|
|
174
198
|
|
|
175
199
|
Editing uses content-oriented read/write. Paths inside the Env must be
|
|
176
|
-
absolute. Host Envs use direct filesystem copy locally and ``
|
|
200
|
+
absolute. Host Envs use direct filesystem copy locally and ``sftp``/``ssh``
|
|
177
201
|
streams remotely. Docker Envs stage through the node with ``docker cp``.
|
|
178
202
|
File bytes never pass through JSON RPC.
|
|
179
203
|
|
|
@@ -193,18 +217,38 @@ replacement that refuses to overwrite a changed remote file.
|
|
|
193
217
|
|
|
194
218
|
Commands execute synchronously and stream stdout and stderr to the terminal as
|
|
195
219
|
they are produced. Cursor or Claude Code should use their native background
|
|
196
|
-
terminal support for long jobs.
|
|
197
|
-
|
|
220
|
+
terminal support for long jobs.
|
|
221
|
+
|
|
222
|
+
Pick **one** form:
|
|
223
|
+
|
|
224
|
+
| Scenario | Form |
|
|
225
|
+
|----------|------|
|
|
226
|
+
| Simple one-liner | `-c '…'` |
|
|
227
|
+
| Quotes, pipes, multi-line | `--file -` + heredoc (see below) |
|
|
228
|
+
| Script on disk | `--file ./script.sh` |
|
|
229
|
+
|
|
230
|
+
**Heredoc** (`<<'EOF'`) is a local-shell mechanism: it writes a multi-line
|
|
231
|
+
string to msdev's **stdin** when you pass `--file -`. Quote the delimiter
|
|
232
|
+
(`<<'EOF'`) so `$` and backticks are not expanded locally. msdev then runs the
|
|
233
|
+
body through a remote shell (`sh -c`), or via shebang if the body starts with
|
|
234
|
+
`#!`.
|
|
198
235
|
|
|
199
236
|
```bash
|
|
200
|
-
msdev exec
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
237
|
+
msdev exec dev-122 --file - <<'EOF'
|
|
238
|
+
python3 -c 'print("no local quoting")'
|
|
239
|
+
grep 'pattern' /var/log/app.log | tail -20
|
|
240
|
+
EOF
|
|
241
|
+
|
|
242
|
+
msdev exec dev-122 -c 'python3 train.py --config "path with spaces" | tee log.txt'
|
|
243
|
+
|
|
244
|
+
msdev exec dev-122 --file ./scripts/run.sh
|
|
206
245
|
```
|
|
207
246
|
|
|
247
|
+
Positional commands after `--` are not supported. The env name is the first
|
|
248
|
+
argument after `exec`; use `-c` for inline strings or `--file` for script
|
|
249
|
+
content (path or `-` for stdin/heredoc). `-c -` is accepted but identical to
|
|
250
|
+
`--file -`; prefer **`--file -`** only.
|
|
251
|
+
|
|
208
252
|
Quoted pipelines and `|` tokens are executed through a remote POSIX shell
|
|
209
253
|
(`sh -c`), so they run on the Node instead of being treated as a single
|
|
210
254
|
executable name. On a Windows `local` Env they use `cmd.exe /s /c`. Prefer
|
|
@@ -7,7 +7,8 @@ A Node owns SSH reachability and `msdevd` deployment. An Env owns the full
|
|
|
7
7
|
execution context: host or Docker runtime, conda/venv/uv layers, optional
|
|
8
8
|
`setup` script (root switch, proxy, etc.), command `wrap`, and static env vars.
|
|
9
9
|
|
|
10
|
-
The CLI is intentionally stateless: execution always names
|
|
10
|
+
The CLI is intentionally stateless: execution always names the env as the first
|
|
11
|
+
`exec` argument.
|
|
11
12
|
MCP is not part of the architecture.
|
|
12
13
|
|
|
13
14
|
## Install
|
|
@@ -21,6 +22,20 @@ msdev --help
|
|
|
21
22
|
|
|
22
23
|
The package installs `msdev` and `msdevd`.
|
|
23
24
|
|
|
25
|
+
Install the agent skill for Cursor and Claude Code, and sync SSH config:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
msdev init
|
|
29
|
+
msdev init --scope project
|
|
30
|
+
msdev init -f
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`init` registers Host aliases from `~/.ssh/config`, prints added/removed
|
|
34
|
+
changes, and writes `skills/msdev-cli/SKILL.md` into `~/.cursor/skills/` and
|
|
35
|
+
`~/.claude/skills/` (or into `.cursor/` / `.claude/` under the current
|
|
36
|
+
directory with `--scope project`). Outdated skill files prompt before
|
|
37
|
+
overwrite; use `-f` to force.
|
|
38
|
+
|
|
24
39
|
## Windows client
|
|
25
40
|
|
|
26
41
|
The typical setup is a **Windows laptop talking to Linux Nodes** via OpenSSH
|
|
@@ -33,13 +48,13 @@ implement ControlMaster multiplexing, so msdev:
|
|
|
33
48
|
RPC (same role as ControlMaster). Explicit `msdev node connect NODE` is
|
|
34
49
|
optional; disable persist with `MSDEV_SSH_LOCAL_FORWARD_PERSIST=0`;
|
|
35
50
|
- reuses that tunnel for captured RPC and default streaming `msdev exec`;
|
|
36
|
-
`env put`/`get` stay on
|
|
51
|
+
`env put`/`get` stay on sftp/ssh streams (file bytes do not go through JSON RPC);
|
|
37
52
|
- hides SSH console windows (`CREATE_NO_WINDOW`) and kills process trees with
|
|
38
53
|
`taskkill /T` on timeout or cancel;
|
|
39
54
|
- SSH is non-interactive: `BatchMode` unless a password is supplied, host keys
|
|
40
55
|
use `accept-new`, and there is no password/passphrase/yes-no prompt. When a
|
|
41
56
|
password is known, injects OpenSSH `SSH_ASKPASS` so `node connect` (and later
|
|
42
|
-
ssh/
|
|
57
|
+
ssh/sftp) can authenticate without a TTY; the local public key is then
|
|
43
58
|
installed on the Node so later logins are passwordless. The password is
|
|
44
59
|
never written to the node registry;
|
|
45
60
|
- serves a TCP loopback endpoint for local `msdevd` when this Python build has
|
|
@@ -57,22 +72,25 @@ If `ssh` is not on PATH, msdev looks in `%SystemRoot%\System32\OpenSSH\`.
|
|
|
57
72
|
|
|
58
73
|
## Nodes and execution environments
|
|
59
74
|
|
|
60
|
-
|
|
75
|
+
Use **`node connect`** as the single entry point: it writes `~/.ssh/config`
|
|
76
|
+
when needed, registers the node, saves passwords, installs the local public
|
|
77
|
+
key, and deploys `msdevd`:
|
|
61
78
|
|
|
62
79
|
```bash
|
|
63
|
-
msdev node
|
|
80
|
+
msdev node connect dev-122 --hostname 80.48.33.133 --user root --password PASSWORD
|
|
81
|
+
msdev node connect dev-122
|
|
82
|
+
msdev node sync-ssh
|
|
83
|
+
msdev node list --ssh
|
|
64
84
|
msdev node list
|
|
65
|
-
msdev node status dev-122
|
|
66
85
|
```
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
|
|
87
|
+
Connect writes or updates a dedicated `Host <name>` block in OpenSSH config.
|
|
88
|
+
The msdev registry stores only the Host alias plus msdevd settings
|
|
89
|
+
(`remote_bin`, `auto_bootstrap`). User, port, keys, and proxy remain in SSH
|
|
90
|
+
config. `node sync-ssh` registers Host aliases that were added manually.
|
|
70
91
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Connect uploads a **static Go msdevd** binary matching the node architecture
|
|
92
|
+
Connect atomically creates a same-named host Env on first use and uploads a
|
|
93
|
+
**static Go msdevd** binary matching the node architecture
|
|
76
94
|
(`linux-amd64` / `linux-arm64`) when the agent is missing or stale. No Python
|
|
77
95
|
is required on the node.
|
|
78
96
|
|
|
@@ -88,19 +106,14 @@ The Go source is in `msdev/`.
|
|
|
88
106
|
|
|
89
107
|
Persistent OpenSSH masters are optional. All SSH from msdev is
|
|
90
108
|
non-interactive: host keys use `accept-new`, and password/passphrase prompts
|
|
91
|
-
are disabled. Supply
|
|
92
|
-
|
|
93
|
-
if missing) so later connections
|
|
109
|
+
are disabled. Supply `--password` on connect; it is saved to ``~/.ssh/config``
|
|
110
|
+
as ``# msdev Password ...`` and used to install the local public key
|
|
111
|
+
(``~/.ssh/id_ed25519``, generated if missing) so later connections can be
|
|
112
|
+
passwordless:
|
|
94
113
|
|
|
95
114
|
```bash
|
|
96
|
-
|
|
97
|
-
export MSDEV_SSH_PASSWORD='...'
|
|
98
|
-
export MSDEV_SSH_PASSWORD_DEV_122='...' # per-node override
|
|
99
|
-
|
|
115
|
+
msdev node connect dev-122 --hostname 80.48.33.133 --user root --password PASSWORD
|
|
100
116
|
msdev node connect dev-122
|
|
101
|
-
msdev node connect dev-122 --password-file FILE
|
|
102
|
-
msdev node connect dev-122 --password-env VAR
|
|
103
|
-
msdev node connect dev-122 --password PASSWORD # non-interactive; visible in ps
|
|
104
117
|
msdev node connect dev-122 --identity FILE # choose which key to install
|
|
105
118
|
msdev node connect dev-122 --no-install-key # password only, do not copy key
|
|
106
119
|
msdev node disconnect dev-122
|
|
@@ -119,6 +132,17 @@ Guides are stored under `~/.config/msdev/guides/nodes/` and
|
|
|
119
132
|
`~/.config/msdev/guides/environments/`. **Node guides** document how to
|
|
120
133
|
connect; **Env guides** document how to initialize shared context (`setup`).
|
|
121
134
|
|
|
135
|
+
Share a full local configuration (registry + guides) with:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
msdev config export ./msdev-config.tar.gz
|
|
139
|
+
msdev config import ./msdev-config.tar.gz
|
|
140
|
+
msdev config import ./msdev-config.tar.gz --force # overwrite name conflicts
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Bundles contain `resources.json`, both guide trees, and a `manifest.json`.
|
|
144
|
+
SSH keys and passwords are never exported.
|
|
145
|
+
|
|
122
146
|
```bash
|
|
123
147
|
msdev env add dev-122-root \
|
|
124
148
|
--node dev-122 \
|
|
@@ -148,7 +172,7 @@ msdev env get dev-122 /srv/project/config.yaml > ./config.yaml
|
|
|
148
172
|
```
|
|
149
173
|
|
|
150
174
|
Editing uses content-oriented read/write. Paths inside the Env must be
|
|
151
|
-
absolute. Host Envs use direct filesystem copy locally and ``
|
|
175
|
+
absolute. Host Envs use direct filesystem copy locally and ``sftp``/``ssh``
|
|
152
176
|
streams remotely. Docker Envs stage through the node with ``docker cp``.
|
|
153
177
|
File bytes never pass through JSON RPC.
|
|
154
178
|
|
|
@@ -168,18 +192,38 @@ replacement that refuses to overwrite a changed remote file.
|
|
|
168
192
|
|
|
169
193
|
Commands execute synchronously and stream stdout and stderr to the terminal as
|
|
170
194
|
they are produced. Cursor or Claude Code should use their native background
|
|
171
|
-
terminal support for long jobs.
|
|
172
|
-
|
|
195
|
+
terminal support for long jobs.
|
|
196
|
+
|
|
197
|
+
Pick **one** form:
|
|
198
|
+
|
|
199
|
+
| Scenario | Form |
|
|
200
|
+
|----------|------|
|
|
201
|
+
| Simple one-liner | `-c '…'` |
|
|
202
|
+
| Quotes, pipes, multi-line | `--file -` + heredoc (see below) |
|
|
203
|
+
| Script on disk | `--file ./script.sh` |
|
|
204
|
+
|
|
205
|
+
**Heredoc** (`<<'EOF'`) is a local-shell mechanism: it writes a multi-line
|
|
206
|
+
string to msdev's **stdin** when you pass `--file -`. Quote the delimiter
|
|
207
|
+
(`<<'EOF'`) so `$` and backticks are not expanded locally. msdev then runs the
|
|
208
|
+
body through a remote shell (`sh -c`), or via shebang if the body starts with
|
|
209
|
+
`#!`.
|
|
173
210
|
|
|
174
211
|
```bash
|
|
175
|
-
msdev exec
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
212
|
+
msdev exec dev-122 --file - <<'EOF'
|
|
213
|
+
python3 -c 'print("no local quoting")'
|
|
214
|
+
grep 'pattern' /var/log/app.log | tail -20
|
|
215
|
+
EOF
|
|
216
|
+
|
|
217
|
+
msdev exec dev-122 -c 'python3 train.py --config "path with spaces" | tee log.txt'
|
|
218
|
+
|
|
219
|
+
msdev exec dev-122 --file ./scripts/run.sh
|
|
181
220
|
```
|
|
182
221
|
|
|
222
|
+
Positional commands after `--` are not supported. The env name is the first
|
|
223
|
+
argument after `exec`; use `-c` for inline strings or `--file` for script
|
|
224
|
+
content (path or `-` for stdin/heredoc). `-c -` is accepted but identical to
|
|
225
|
+
`--file -`; prefer **`--file -`** only.
|
|
226
|
+
|
|
183
227
|
Quoted pipelines and `|` tokens are executed through a remote POSIX shell
|
|
184
228
|
(`sh -c`), so they run on the Node instead of being treated as a single
|
|
185
229
|
executable name. On a Windows `local` Env they use `cmd.exe /s /c`. Prefer
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "msdev"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.13.0"
|
|
8
8
|
description = "Portable nodes and execution environments for msModelSlim development"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -44,7 +44,11 @@ package-dir = { "" = "src" }
|
|
|
44
44
|
where = ["src"]
|
|
45
45
|
|
|
46
46
|
[tool.setuptools.package-data]
|
|
47
|
-
msdev = [
|
|
47
|
+
msdev = [
|
|
48
|
+
"helpers/msdev-file-helper-*",
|
|
49
|
+
"helpers/msdevd-linux-*",
|
|
50
|
+
"skills/msdev-cli/SKILL.md",
|
|
51
|
+
]
|
|
48
52
|
|
|
49
53
|
[tool.pytest.ini_options]
|
|
50
54
|
testpaths = ["tests"]
|