msdev 0.12.0__tar.gz → 0.14.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.14.0}/PKG-INFO +81 -35
- {msdev-0.12.0 → msdev-0.14.0}/README.md +80 -34
- {msdev-0.12.0 → msdev-0.14.0}/pyproject.toml +6 -2
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/__init__.py +1 -1
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/cli.py +396 -67
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/compat.py +6 -6
- msdev-0.14.0/src/msdev/core/config_bundle.py +338 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/env_transfer.py +30 -29
- msdev-0.14.0/src/msdev/core/exec_argv.py +196 -0
- msdev-0.14.0/src/msdev/core/init_setup.py +42 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/node.py +168 -17
- msdev-0.14.0/src/msdev/core/sftp_transfer.py +156 -0
- msdev-0.14.0/src/msdev/core/skill_install.py +258 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/ssh_auth.py +72 -82
- msdev-0.14.0/src/msdev/core/ssh_config.py +380 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/ssh_tunnel.py +5 -2
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/stream_transport.py +9 -3
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/transport.py +84 -48
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/helpers/msdevd-linux-amd64 +0 -0
- msdev-0.14.0/src/msdev/helpers/msdevd-linux-amd64.sha256 +1 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/helpers/msdevd-linux-arm64 +0 -0
- msdev-0.14.0/src/msdev/helpers/msdevd-linux-arm64.sha256 +1 -0
- msdev-0.14.0/src/msdev/skills/msdev-cli/SKILL.md +186 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev.egg-info/PKG-INFO +81 -35
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev.egg-info/SOURCES.txt +15 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_cli.py +62 -33
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_cli_only_architecture.py +17 -5
- msdev-0.14.0/tests/test_config_bundle.py +224 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_daemon.py +1 -1
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_daemon_deploy.py +16 -11
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_env_transfer.py +16 -11
- msdev-0.14.0/tests/test_exec_argv.py +133 -0
- msdev-0.14.0/tests/test_exec_command_scenario.py +152 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_exec_default_timeout_scenario.py +2 -8
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_go_msdevd_scenario.py +1 -1
- msdev-0.14.0/tests/test_init_skill.py +241 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_msdev_cli_skill.py +22 -4
- msdev-0.14.0/tests/test_node_bootstrap_version_scenario.py +173 -0
- msdev-0.14.0/tests/test_node_connect_provision_scenario.py +104 -0
- msdev-0.14.0/tests/test_node_connect_save_password_scenario.py +87 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_node_env_services.py +17 -8
- msdev-0.14.0/tests/test_node_sync_ssh_scenario.py +76 -0
- msdev-0.14.0/tests/test_sftp_transfer_scenario.py +239 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_ssh_auth.py +75 -58
- msdev-0.14.0/tests/test_ssh_config.py +171 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_target_exec_services.py +68 -9
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_transport.py +54 -31
- {msdev-0.12.0 → msdev-0.14.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.14.0}/LICENSE +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/setup.cfg +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/__init__.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/config.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/container_helper.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/daemon_deploy.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/guides.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/helper_deploy.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/host_files.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/host_mutations.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/inventory.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/limits.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/local_rpc.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/multiplex.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/request_client.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/resources.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/__init__.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/capabilities.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/context.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/environment.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/execution.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/model.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/npu.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/services/results.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/stream_limits.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/stream_server.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/core/streamproto.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/daemon.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/helpers/msdev-file-helper-linux-amd64 +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/helpers/msdev-file-helper-linux-amd64.sha256 +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/helpers/msdev-file-helper-linux-arm64 +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev/helpers/msdev-file-helper-linux-arm64.sha256 +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev.egg-info/dependency_links.txt +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev.egg-info/entry_points.txt +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/src/msdev.egg-info/top_level.txt +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_compat.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_config.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_connect_env_scenario.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_container_helper.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_daemon_container_stream.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_docker_stream_dispatch.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_env_put_get_scenario.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_env_read_write_scenario.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_helper_deploy.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_inventory.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_model_cli.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_model_services.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_multiplex.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_node_env_config.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_request_client.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_ssh_tunnel.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_stream_server.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_stream_transport.py +0 -0
- {msdev-0.12.0 → msdev-0.14.0}/tests/test_streamproto.py +0 -0
- {msdev-0.12.0 → msdev-0.14.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.14.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,24 +97,29 @@ 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 bootstrap dev-122
|
|
108
|
+
msdev node sync-ssh
|
|
109
|
+
msdev node list --ssh
|
|
89
110
|
msdev node list
|
|
90
|
-
msdev node status dev-122
|
|
91
111
|
```
|
|
92
112
|
|
|
93
|
-
|
|
94
|
-
|
|
113
|
+
Connect writes or updates a dedicated `Host <name>` block in OpenSSH config.
|
|
114
|
+
The msdev registry stores only the Host alias plus msdevd settings
|
|
115
|
+
(`remote_bin`, `auto_bootstrap`). User, port, keys, and proxy remain in SSH
|
|
116
|
+
config. `node sync-ssh` registers Host aliases that were added manually.
|
|
95
117
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
(`linux-amd64` / `linux-arm64`) when the agent is missing or stale. No Python
|
|
102
|
-
is required on the node.
|
|
118
|
+
Connect atomically creates a same-named host Env on first use and uploads a
|
|
119
|
+
**static Go msdevd** binary matching the node architecture
|
|
120
|
+
(`linux-amd64` / `linux-arm64`) when the agent is missing or when the remote
|
|
121
|
+
`ping` version does not match the local CLI. Use **`msdev node bootstrap NODE`**
|
|
122
|
+
to force a redeploy after upgrading msdev. No Python is required on the node.
|
|
103
123
|
|
|
104
124
|
Build the static daemons before release or local testing:
|
|
105
125
|
|
|
@@ -113,19 +133,14 @@ The Go source is in `msdev/`.
|
|
|
113
133
|
|
|
114
134
|
Persistent OpenSSH masters are optional. All SSH from msdev is
|
|
115
135
|
non-interactive: host keys use `accept-new`, and password/passphrase prompts
|
|
116
|
-
are disabled. Supply
|
|
117
|
-
|
|
118
|
-
if missing) so later connections
|
|
136
|
+
are disabled. Supply `--password` on connect; it is saved to ``~/.ssh/config``
|
|
137
|
+
as ``# msdev Password ...`` and used to install the local public key
|
|
138
|
+
(``~/.ssh/id_ed25519``, generated if missing) so later connections can be
|
|
139
|
+
passwordless:
|
|
119
140
|
|
|
120
141
|
```bash
|
|
121
|
-
|
|
122
|
-
export MSDEV_SSH_PASSWORD='...'
|
|
123
|
-
export MSDEV_SSH_PASSWORD_DEV_122='...' # per-node override
|
|
124
|
-
|
|
142
|
+
msdev node connect dev-122 --hostname 80.48.33.133 --user root --password PASSWORD
|
|
125
143
|
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
144
|
msdev node connect dev-122 --identity FILE # choose which key to install
|
|
130
145
|
msdev node connect dev-122 --no-install-key # password only, do not copy key
|
|
131
146
|
msdev node disconnect dev-122
|
|
@@ -144,6 +159,17 @@ Guides are stored under `~/.config/msdev/guides/nodes/` and
|
|
|
144
159
|
`~/.config/msdev/guides/environments/`. **Node guides** document how to
|
|
145
160
|
connect; **Env guides** document how to initialize shared context (`setup`).
|
|
146
161
|
|
|
162
|
+
Share a full local configuration (registry + guides) with:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
msdev config export ./msdev-config.tar.gz
|
|
166
|
+
msdev config import ./msdev-config.tar.gz
|
|
167
|
+
msdev config import ./msdev-config.tar.gz --force # overwrite name conflicts
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Bundles contain `resources.json`, both guide trees, and a `manifest.json`.
|
|
171
|
+
SSH keys and passwords are never exported.
|
|
172
|
+
|
|
147
173
|
```bash
|
|
148
174
|
msdev env add dev-122-root \
|
|
149
175
|
--node dev-122 \
|
|
@@ -173,7 +199,7 @@ msdev env get dev-122 /srv/project/config.yaml > ./config.yaml
|
|
|
173
199
|
```
|
|
174
200
|
|
|
175
201
|
Editing uses content-oriented read/write. Paths inside the Env must be
|
|
176
|
-
absolute. Host Envs use direct filesystem copy locally and ``
|
|
202
|
+
absolute. Host Envs use direct filesystem copy locally and ``sftp``/``ssh``
|
|
177
203
|
streams remotely. Docker Envs stage through the node with ``docker cp``.
|
|
178
204
|
File bytes never pass through JSON RPC.
|
|
179
205
|
|
|
@@ -193,18 +219,38 @@ replacement that refuses to overwrite a changed remote file.
|
|
|
193
219
|
|
|
194
220
|
Commands execute synchronously and stream stdout and stderr to the terminal as
|
|
195
221
|
they are produced. Cursor or Claude Code should use their native background
|
|
196
|
-
terminal support for long jobs.
|
|
197
|
-
|
|
222
|
+
terminal support for long jobs.
|
|
223
|
+
|
|
224
|
+
Pick **one** form:
|
|
225
|
+
|
|
226
|
+
| Scenario | Form |
|
|
227
|
+
|----------|------|
|
|
228
|
+
| Simple one-liner | `-c '…'` |
|
|
229
|
+
| Quotes, pipes, multi-line | `--file -` + heredoc (see below) |
|
|
230
|
+
| Script on disk | `--file ./script.sh` |
|
|
231
|
+
|
|
232
|
+
**Heredoc** (`<<'EOF'`) is a local-shell mechanism: it writes a multi-line
|
|
233
|
+
string to msdev's **stdin** when you pass `--file -`. Quote the delimiter
|
|
234
|
+
(`<<'EOF'`) so `$` and backticks are not expanded locally. msdev then runs the
|
|
235
|
+
body through a remote shell (`sh -c`), or via shebang if the body starts with
|
|
236
|
+
`#!`.
|
|
198
237
|
|
|
199
238
|
```bash
|
|
200
|
-
msdev exec
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
239
|
+
msdev exec dev-122 --file - <<'EOF'
|
|
240
|
+
python3 -c 'print("no local quoting")'
|
|
241
|
+
grep 'pattern' /var/log/app.log | tail -20
|
|
242
|
+
EOF
|
|
243
|
+
|
|
244
|
+
msdev exec dev-122 -c 'python3 train.py --config "path with spaces" | tee log.txt'
|
|
245
|
+
|
|
246
|
+
msdev exec dev-122 --file ./scripts/run.sh
|
|
206
247
|
```
|
|
207
248
|
|
|
249
|
+
Positional commands after `--` are not supported. The env name is the first
|
|
250
|
+
argument after `exec`; use `-c` for inline strings or `--file` for script
|
|
251
|
+
content (path or `-` for stdin/heredoc). `-c -` is accepted but identical to
|
|
252
|
+
`--file -`; prefer **`--file -`** only.
|
|
253
|
+
|
|
208
254
|
Quoted pipelines and `|` tokens are executed through a remote POSIX shell
|
|
209
255
|
(`sh -c`), so they run on the Node instead of being treated as a single
|
|
210
256
|
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,24 +72,29 @@ 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 bootstrap dev-122
|
|
83
|
+
msdev node sync-ssh
|
|
84
|
+
msdev node list --ssh
|
|
64
85
|
msdev node list
|
|
65
|
-
msdev node status dev-122
|
|
66
86
|
```
|
|
67
87
|
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
Connect writes or updates a dedicated `Host <name>` block in OpenSSH config.
|
|
89
|
+
The msdev registry stores only the Host alias plus msdevd settings
|
|
90
|
+
(`remote_bin`, `auto_bootstrap`). User, port, keys, and proxy remain in SSH
|
|
91
|
+
config. `node sync-ssh` registers Host aliases that were added manually.
|
|
70
92
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
(`linux-amd64` / `linux-arm64`) when the agent is missing or stale. No Python
|
|
77
|
-
is required on the node.
|
|
93
|
+
Connect atomically creates a same-named host Env on first use and uploads a
|
|
94
|
+
**static Go msdevd** binary matching the node architecture
|
|
95
|
+
(`linux-amd64` / `linux-arm64`) when the agent is missing or when the remote
|
|
96
|
+
`ping` version does not match the local CLI. Use **`msdev node bootstrap NODE`**
|
|
97
|
+
to force a redeploy after upgrading msdev. No Python is required on the node.
|
|
78
98
|
|
|
79
99
|
Build the static daemons before release or local testing:
|
|
80
100
|
|
|
@@ -88,19 +108,14 @@ The Go source is in `msdev/`.
|
|
|
88
108
|
|
|
89
109
|
Persistent OpenSSH masters are optional. All SSH from msdev is
|
|
90
110
|
non-interactive: host keys use `accept-new`, and password/passphrase prompts
|
|
91
|
-
are disabled. Supply
|
|
92
|
-
|
|
93
|
-
if missing) so later connections
|
|
111
|
+
are disabled. Supply `--password` on connect; it is saved to ``~/.ssh/config``
|
|
112
|
+
as ``# msdev Password ...`` and used to install the local public key
|
|
113
|
+
(``~/.ssh/id_ed25519``, generated if missing) so later connections can be
|
|
114
|
+
passwordless:
|
|
94
115
|
|
|
95
116
|
```bash
|
|
96
|
-
|
|
97
|
-
export MSDEV_SSH_PASSWORD='...'
|
|
98
|
-
export MSDEV_SSH_PASSWORD_DEV_122='...' # per-node override
|
|
99
|
-
|
|
117
|
+
msdev node connect dev-122 --hostname 80.48.33.133 --user root --password PASSWORD
|
|
100
118
|
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
119
|
msdev node connect dev-122 --identity FILE # choose which key to install
|
|
105
120
|
msdev node connect dev-122 --no-install-key # password only, do not copy key
|
|
106
121
|
msdev node disconnect dev-122
|
|
@@ -119,6 +134,17 @@ Guides are stored under `~/.config/msdev/guides/nodes/` and
|
|
|
119
134
|
`~/.config/msdev/guides/environments/`. **Node guides** document how to
|
|
120
135
|
connect; **Env guides** document how to initialize shared context (`setup`).
|
|
121
136
|
|
|
137
|
+
Share a full local configuration (registry + guides) with:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
msdev config export ./msdev-config.tar.gz
|
|
141
|
+
msdev config import ./msdev-config.tar.gz
|
|
142
|
+
msdev config import ./msdev-config.tar.gz --force # overwrite name conflicts
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Bundles contain `resources.json`, both guide trees, and a `manifest.json`.
|
|
146
|
+
SSH keys and passwords are never exported.
|
|
147
|
+
|
|
122
148
|
```bash
|
|
123
149
|
msdev env add dev-122-root \
|
|
124
150
|
--node dev-122 \
|
|
@@ -148,7 +174,7 @@ msdev env get dev-122 /srv/project/config.yaml > ./config.yaml
|
|
|
148
174
|
```
|
|
149
175
|
|
|
150
176
|
Editing uses content-oriented read/write. Paths inside the Env must be
|
|
151
|
-
absolute. Host Envs use direct filesystem copy locally and ``
|
|
177
|
+
absolute. Host Envs use direct filesystem copy locally and ``sftp``/``ssh``
|
|
152
178
|
streams remotely. Docker Envs stage through the node with ``docker cp``.
|
|
153
179
|
File bytes never pass through JSON RPC.
|
|
154
180
|
|
|
@@ -168,18 +194,38 @@ replacement that refuses to overwrite a changed remote file.
|
|
|
168
194
|
|
|
169
195
|
Commands execute synchronously and stream stdout and stderr to the terminal as
|
|
170
196
|
they are produced. Cursor or Claude Code should use their native background
|
|
171
|
-
terminal support for long jobs.
|
|
172
|
-
|
|
197
|
+
terminal support for long jobs.
|
|
198
|
+
|
|
199
|
+
Pick **one** form:
|
|
200
|
+
|
|
201
|
+
| Scenario | Form |
|
|
202
|
+
|----------|------|
|
|
203
|
+
| Simple one-liner | `-c '…'` |
|
|
204
|
+
| Quotes, pipes, multi-line | `--file -` + heredoc (see below) |
|
|
205
|
+
| Script on disk | `--file ./script.sh` |
|
|
206
|
+
|
|
207
|
+
**Heredoc** (`<<'EOF'`) is a local-shell mechanism: it writes a multi-line
|
|
208
|
+
string to msdev's **stdin** when you pass `--file -`. Quote the delimiter
|
|
209
|
+
(`<<'EOF'`) so `$` and backticks are not expanded locally. msdev then runs the
|
|
210
|
+
body through a remote shell (`sh -c`), or via shebang if the body starts with
|
|
211
|
+
`#!`.
|
|
173
212
|
|
|
174
213
|
```bash
|
|
175
|
-
msdev exec
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
214
|
+
msdev exec dev-122 --file - <<'EOF'
|
|
215
|
+
python3 -c 'print("no local quoting")'
|
|
216
|
+
grep 'pattern' /var/log/app.log | tail -20
|
|
217
|
+
EOF
|
|
218
|
+
|
|
219
|
+
msdev exec dev-122 -c 'python3 train.py --config "path with spaces" | tee log.txt'
|
|
220
|
+
|
|
221
|
+
msdev exec dev-122 --file ./scripts/run.sh
|
|
181
222
|
```
|
|
182
223
|
|
|
224
|
+
Positional commands after `--` are not supported. The env name is the first
|
|
225
|
+
argument after `exec`; use `-c` for inline strings or `--file` for script
|
|
226
|
+
content (path or `-` for stdin/heredoc). `-c -` is accepted but identical to
|
|
227
|
+
`--file -`; prefer **`--file -`** only.
|
|
228
|
+
|
|
183
229
|
Quoted pipelines and `|` tokens are executed through a remote POSIX shell
|
|
184
230
|
(`sh -c`), so they run on the Node instead of being treated as a single
|
|
185
231
|
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.14.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"]
|