msdev 0.10.0__tar.gz → 0.10.1__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.10.0 → msdev-0.10.1}/PKG-INFO +66 -121
- {msdev-0.10.0 → msdev-0.10.1}/README.md +64 -120
- {msdev-0.10.0 → msdev-0.10.1}/pyproject.toml +2 -1
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/__init__.py +1 -1
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/cli.py +148 -485
- msdev-0.10.1/src/msdev/core/__init__.py +1 -0
- msdev-0.10.1/src/msdev/core/compat.py +182 -0
- msdev-0.10.1/src/msdev/core/config.py +373 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/container_helper.py +13 -6
- msdev-0.10.1/src/msdev/core/env_transfer.py +364 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/host_mutations.py +1 -1
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/limits.py +2 -2
- msdev-0.10.1/src/msdev/core/local_rpc.py +85 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/resources.py +4 -2
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/__init__.py +10 -22
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/capabilities.py +3 -23
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/context.py +0 -2
- msdev-0.10.1/src/msdev/core/services/environment.py +331 -0
- msdev-0.10.1/src/msdev/core/ssh_tunnel.py +552 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/stream_server.py +14 -4
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/stream_transport.py +21 -14
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/transport.py +283 -88
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/daemon.py +112 -176
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev.egg-info/PKG-INFO +66 -121
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev.egg-info/SOURCES.txt +11 -13
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_cli.py +1 -303
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_cli_only_architecture.py +4 -7
- msdev-0.10.1/tests/test_compat.py +45 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_config.py +82 -1
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_daemon.py +76 -59
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_daemon_container_stream.py +1 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_docker_stream_dispatch.py +7 -2
- msdev-0.10.1/tests/test_env_put_get_scenario.py +134 -0
- msdev-0.10.1/tests/test_env_read_write_scenario.py +134 -0
- msdev-0.10.1/tests/test_env_transfer.py +61 -0
- msdev-0.10.1/tests/test_exec_default_timeout_scenario.py +134 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_model_services.py +0 -2
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_msdev_cli_skill.py +9 -9
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_multiplex.py +12 -3
- msdev-0.10.1/tests/test_node_env_services.py +187 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_request_client.py +10 -4
- msdev-0.10.1/tests/test_ssh_tunnel.py +57 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_stream_server.py +10 -3
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_stream_transport.py +9 -4
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_target_exec_services.py +0 -3
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_transport.py +210 -17
- msdev-0.10.1/tests/test_windows_local_scenario.py +87 -0
- msdev-0.10.0/src/msdev/core/__init__.py +0 -1
- msdev-0.10.0/src/msdev/core/config.py +0 -193
- msdev-0.10.0/src/msdev/core/services/environment.py +0 -84
- msdev-0.10.0/src/msdev/core/services/workspace.py +0 -567
- msdev-0.10.0/src/msdev/core/workspace/__init__.py +0 -43
- msdev-0.10.0/src/msdev/core/workspace/access.py +0 -1216
- msdev-0.10.0/src/msdev/core/workspace/client.py +0 -329
- msdev-0.10.0/src/msdev/core/workspace/paths.py +0 -65
- msdev-0.10.0/src/msdev/core/workspace/registry.py +0 -189
- msdev-0.10.0/src/msdev/session/__init__.py +0 -13
- msdev-0.10.0/src/msdev/session/export.py +0 -190
- msdev-0.10.0/src/msdev/session/log.py +0 -269
- msdev-0.10.0/tests/test_cli_session.py +0 -202
- msdev-0.10.0/tests/test_node_env_services.py +0 -63
- msdev-0.10.0/tests/test_workspace.py +0 -855
- msdev-0.10.0/tests/test_workspace_client.py +0 -321
- msdev-0.10.0/tests/test_workspace_services.py +0 -414
- {msdev-0.10.0 → msdev-0.10.1}/LICENSE +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/setup.cfg +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/guides.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/helper_deploy.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/host_files.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/inventory.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/multiplex.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/request_client.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/execution.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/model.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/node.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/npu.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/services/results.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/stream_limits.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev/core/streamproto.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev.egg-info/dependency_links.txt +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev.egg-info/entry_points.txt +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/src/msdev.egg-info/top_level.txt +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_container_helper.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_helper_deploy.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_inventory.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_model_cli.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_node_env_config.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_streamproto.py +0 -0
- {msdev-0.10.0 → msdev-0.10.1}/tests/test_target_guides.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: msdev
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.1
|
|
4
4
|
Summary: Portable nodes and execution environments for msModelSlim development
|
|
5
5
|
Author: msModelSlim Agent Contributors
|
|
6
6
|
License-Expression: MulanPSL-2.0
|
|
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
17
|
Classifier: Operating System :: MacOS
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
19
|
Classifier: Operating System :: POSIX :: Linux
|
|
19
20
|
Classifier: Topic :: Software Development :: Build Tools
|
|
20
21
|
Requires-Python: >=3.10
|
|
@@ -32,7 +33,6 @@ The CLI is intentionally stateless:
|
|
|
32
33
|
|
|
33
34
|
- Node-scoped NPU/model operations name `--node` or use `--all`;
|
|
34
35
|
- execution names `--env`;
|
|
35
|
-
- every workspace operation names the registered workspace;
|
|
36
36
|
- no harness conversation binding or implicit current Env exists;
|
|
37
37
|
- MCP is not part of the architecture.
|
|
38
38
|
|
|
@@ -47,6 +47,34 @@ msdev --help
|
|
|
47
47
|
|
|
48
48
|
The package installs `msdev` and `msdevd`.
|
|
49
49
|
|
|
50
|
+
## Windows client
|
|
51
|
+
|
|
52
|
+
The typical setup is a **Windows laptop talking to Linux Nodes** via OpenSSH
|
|
53
|
+
(`C:\Windows\System32\OpenSSH\ssh.exe`). Native Windows OpenSSH does not
|
|
54
|
+
implement ControlMaster multiplexing, so msdev:
|
|
55
|
+
|
|
56
|
+
- omits `ControlMaster`/`ControlPath` on Windows (override with
|
|
57
|
+
`MSDEV_SSH_CONTROL_MASTER=1` only if your SSH client actually supports mux);
|
|
58
|
+
- starts a persistent `ssh -L` LocalForward tunnel automatically on the first
|
|
59
|
+
RPC (same role as ControlMaster). Explicit `msdev node connect NODE` is
|
|
60
|
+
optional; disable persist with `MSDEV_SSH_LOCAL_FORWARD_PERSIST=0`;
|
|
61
|
+
- reuses that tunnel for captured RPC and default streaming `msdev exec`;
|
|
62
|
+
`env put`/`get` stay on scp/ssh streams (file bytes do not go through JSON RPC);
|
|
63
|
+
- hides SSH console windows (`CREATE_NO_WINDOW`) and kills process trees with
|
|
64
|
+
`taskkill /T` on timeout or cancel;
|
|
65
|
+
- serves a TCP loopback endpoint for local `msdevd` when this Python build has
|
|
66
|
+
no `AF_UNIX` sockets.
|
|
67
|
+
|
|
68
|
+
Install with `python -m pip install -e .`. `install-user.py` writes
|
|
69
|
+
`msdev.cmd` / `msdevd.cmd` under `%USERPROFILE%\.local\bin`.
|
|
70
|
+
|
|
71
|
+
Remote paths inside a Linux Env remain POSIX (`/srv/...`). Local `env put`/`get`
|
|
72
|
+
on Windows accept Windows absolute paths (`C:\...`).
|
|
73
|
+
|
|
74
|
+
Local `exec` on Windows wraps Conda with `conda run` and venvs with
|
|
75
|
+
`Scripts\activate.bat` (remote Linux Nodes still use POSIX `sh`/`bash` wrappers).
|
|
76
|
+
If `ssh` is not on PATH, msdev looks in `%SystemRoot%\System32\OpenSSH\`.
|
|
77
|
+
|
|
50
78
|
## Nodes and execution environments
|
|
51
79
|
|
|
52
80
|
Register a host from `~/.ssh/config`:
|
|
@@ -107,6 +135,33 @@ msdev env add dev-122-vllm \
|
|
|
107
135
|
--layer venv:/srv/project/.venv
|
|
108
136
|
```
|
|
109
137
|
|
|
138
|
+
## File put, get, read, and write
|
|
139
|
+
|
|
140
|
+
Bulk transfer copies a local file into an Env filesystem, or fetches one back:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
msdev env put dev-122 ./config.yaml /srv/project/config.yaml
|
|
144
|
+
msdev env get dev-122 /srv/project/config.yaml --output ./config.yaml
|
|
145
|
+
msdev env get dev-122 /srv/project/config.yaml > ./config.yaml
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Editing uses content-oriented read/write. Paths inside the Env must be
|
|
149
|
+
absolute. Host Envs use direct filesystem copy locally and ``scp``/``ssh``
|
|
150
|
+
streams remotely. Docker Envs stage through the node with ``docker cp``.
|
|
151
|
+
File bytes never pass through JSON RPC.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
msdev env read dev-122 /srv/project/config.yaml
|
|
155
|
+
msdev env read dev-122 /srv/project/config.yaml --json
|
|
156
|
+
msdev env write dev-122 /srv/project/note.md --file /tmp/note.md
|
|
157
|
+
msdev env write dev-122 /srv/project/note.md < /tmp/note.md
|
|
158
|
+
msdev env write dev-122 /srv/project/note.md --file /tmp/note.md \
|
|
159
|
+
--expected-sha256 <digest>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Read before replacing an existing file. `--expected-sha256` is compare-and-swap
|
|
163
|
+
replacement that refuses to overwrite a changed remote file.
|
|
164
|
+
|
|
110
165
|
## NPU inventory
|
|
111
166
|
|
|
112
167
|
```bash
|
|
@@ -130,8 +185,8 @@ msdev exec \
|
|
|
130
185
|
-- python3 run.py
|
|
131
186
|
```
|
|
132
187
|
|
|
133
|
-
`--timeout-seconds` defaults to
|
|
134
|
-
|
|
188
|
+
`--timeout-seconds` defaults to `-1` (no deadline). Any positive finite duration
|
|
189
|
+
is also accepted. A positive timeout kills the complete command
|
|
135
190
|
process group and returns exit code 124. Cancelling the local CLI closes the RPC
|
|
136
191
|
connection, causing `msdevd` to kill and reap the remote process group. Finite
|
|
137
192
|
SSH/Unix RPC deadlines include a short completion grace for output drain and
|
|
@@ -140,66 +195,6 @@ serialization.
|
|
|
140
195
|
`--result-json` selects captured, non-streaming execution and prints one
|
|
141
196
|
structured JSON result containing stdout and stderr.
|
|
142
197
|
|
|
143
|
-
## Remote workspaces
|
|
144
|
-
|
|
145
|
-
A workspace gives a stable name to an Env and filesystem root:
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
msdev workspace add project \
|
|
149
|
-
--env dev-122 \
|
|
150
|
-
--root /srv/project
|
|
151
|
-
|
|
152
|
-
msdev workspace list
|
|
153
|
-
msdev workspace inspect project
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Workspace operations are file- and Git-oriented. There is no
|
|
157
|
-
`msdev workspace exec`; use `msdev exec --env ... --cwd ...` for commands.
|
|
158
|
-
|
|
159
|
-
### Read and inspect
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
msdev workspace stat project README.md
|
|
163
|
-
msdev workspace read project README.md
|
|
164
|
-
msdev workspace read project weights.bin --output /tmp/weights.bin
|
|
165
|
-
msdev workspace list project src --json
|
|
166
|
-
msdev workspace glob project '**/*.py' --json
|
|
167
|
-
msdev workspace search project 'TODO' src tests --json
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Write safely
|
|
171
|
-
|
|
172
|
-
For non-trivial content, use stdin or `--file` rather than shell-escaped
|
|
173
|
-
`--content`:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
msdev workspace write project docs/note.md < /tmp/note.md
|
|
177
|
-
msdev workspace write project docs/note.md --file /tmp/note.md
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Compare-and-swap replacement prevents overwriting a changed remote file:
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
msdev workspace apply-patch project docs/note.md \
|
|
184
|
-
--file /tmp/note.md \
|
|
185
|
-
--expected-sha256 <digest>
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Delete an explicit remote file:
|
|
189
|
-
|
|
190
|
-
```bash
|
|
191
|
-
msdev workspace delete project docs/obsolete.md
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Git
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
msdev workspace git-status project --result-json
|
|
198
|
-
msdev workspace git-diff project --result-json -- --stat
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Git diff rejects options that can write files or invoke external diff helpers.
|
|
202
|
-
|
|
203
198
|
## Model inventory
|
|
204
199
|
|
|
205
200
|
Examples:
|
|
@@ -216,59 +211,6 @@ msdev model audit --node dev-122
|
|
|
216
211
|
Use `msdev model --help` and the individual subcommand help for register,
|
|
217
212
|
update, replicas, refresh, verify, export, import, and rebind.
|
|
218
213
|
|
|
219
|
-
## Explicit CLI sessions and runbooks
|
|
220
|
-
|
|
221
|
-
Create a session before a reproducible workflow:
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
msdev session begin --name qwen3-quant --json
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
Pass the returned ID explicitly or set it in a persistent terminal:
|
|
228
|
-
|
|
229
|
-
```bash
|
|
230
|
-
export MSDEV_SESSION_ID=<session-id>
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
Intent metadata is global and must appear before the subcommand:
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
msdev \
|
|
237
|
-
--session-id <session-id> \
|
|
238
|
-
--intent-kind execution \
|
|
239
|
-
--intent-summary 'Run Qwen3 quantization' \
|
|
240
|
-
--intent-phase quantization \
|
|
241
|
-
--intent-step-id quant-1 \
|
|
242
|
-
exec --env dev-122 --timeout-seconds 1800 -- python3 quant.py
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
Intent kinds:
|
|
246
|
-
|
|
247
|
-
- `execution`: core reproduction step;
|
|
248
|
-
- `verification`: optional confirmation;
|
|
249
|
-
- `diagnostic`: troubleshooting, excluded from core steps;
|
|
250
|
-
- `exploration`: discovery, excluded from core steps.
|
|
251
|
-
|
|
252
|
-
Each invocation receives a unique `operation_id`. `session_id` groups CLI
|
|
253
|
-
operations only; it never supplies a Node, Env, or workspace default.
|
|
254
|
-
|
|
255
|
-
Logs are private JSONL files under:
|
|
256
|
-
|
|
257
|
-
```text
|
|
258
|
-
${XDG_STATE_HOME:-~/.local/state}/msdev/sessions/
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
They retain sanitized logical arguments, preview, explicit resource, intent,
|
|
262
|
-
exit code, and elapsed time. Command stdout/stderr and environment values are
|
|
263
|
-
not duplicated into logs.
|
|
264
|
-
|
|
265
|
-
```bash
|
|
266
|
-
msdev session list
|
|
267
|
-
msdev session export --session-id <session-id> --output runbook.md
|
|
268
|
-
msdev session export --latest --detail normal --output runbook.md
|
|
269
|
-
msdev session export --input /path/to/session.jsonl --detail full
|
|
270
|
-
```
|
|
271
|
-
|
|
272
214
|
## Architecture
|
|
273
215
|
|
|
274
216
|
```text
|
|
@@ -276,15 +218,18 @@ msdev CLI
|
|
|
276
218
|
-> typed core service
|
|
277
219
|
-> UnixRpcTransport or SshRpcTransport
|
|
278
220
|
-> per-user msdevd
|
|
279
|
-
-> host/container command,
|
|
221
|
+
-> host/container command, env file transfer, NPU, or inventory
|
|
280
222
|
```
|
|
281
223
|
|
|
282
|
-
Remote RPC responses and command output are bounded.
|
|
283
|
-
|
|
284
|
-
compare-and-swap. Node/Env and workspace registries use locked atomic updates.
|
|
224
|
+
Remote RPC responses and command output are bounded. Node/Env registries use
|
|
225
|
+
locked atomic updates.
|
|
285
226
|
|
|
286
227
|
## Testing
|
|
287
228
|
|
|
288
229
|
```bash
|
|
289
230
|
python3 -m unittest discover -s tests -v
|
|
290
231
|
```
|
|
232
|
+
|
|
233
|
+
Feature work must include at least one actual scenario test on the real
|
|
234
|
+
control path (`msdev` CLI → service → transport → `msdevd` → effect). Unit
|
|
235
|
+
tests alone are not sufficient.
|
|
@@ -8,7 +8,6 @@ The CLI is intentionally stateless:
|
|
|
8
8
|
|
|
9
9
|
- Node-scoped NPU/model operations name `--node` or use `--all`;
|
|
10
10
|
- execution names `--env`;
|
|
11
|
-
- every workspace operation names the registered workspace;
|
|
12
11
|
- no harness conversation binding or implicit current Env exists;
|
|
13
12
|
- MCP is not part of the architecture.
|
|
14
13
|
|
|
@@ -23,6 +22,34 @@ msdev --help
|
|
|
23
22
|
|
|
24
23
|
The package installs `msdev` and `msdevd`.
|
|
25
24
|
|
|
25
|
+
## Windows client
|
|
26
|
+
|
|
27
|
+
The typical setup is a **Windows laptop talking to Linux Nodes** via OpenSSH
|
|
28
|
+
(`C:\Windows\System32\OpenSSH\ssh.exe`). Native Windows OpenSSH does not
|
|
29
|
+
implement ControlMaster multiplexing, so msdev:
|
|
30
|
+
|
|
31
|
+
- omits `ControlMaster`/`ControlPath` on Windows (override with
|
|
32
|
+
`MSDEV_SSH_CONTROL_MASTER=1` only if your SSH client actually supports mux);
|
|
33
|
+
- starts a persistent `ssh -L` LocalForward tunnel automatically on the first
|
|
34
|
+
RPC (same role as ControlMaster). Explicit `msdev node connect NODE` is
|
|
35
|
+
optional; disable persist with `MSDEV_SSH_LOCAL_FORWARD_PERSIST=0`;
|
|
36
|
+
- reuses that tunnel for captured RPC and default streaming `msdev exec`;
|
|
37
|
+
`env put`/`get` stay on scp/ssh streams (file bytes do not go through JSON RPC);
|
|
38
|
+
- hides SSH console windows (`CREATE_NO_WINDOW`) and kills process trees with
|
|
39
|
+
`taskkill /T` on timeout or cancel;
|
|
40
|
+
- serves a TCP loopback endpoint for local `msdevd` when this Python build has
|
|
41
|
+
no `AF_UNIX` sockets.
|
|
42
|
+
|
|
43
|
+
Install with `python -m pip install -e .`. `install-user.py` writes
|
|
44
|
+
`msdev.cmd` / `msdevd.cmd` under `%USERPROFILE%\.local\bin`.
|
|
45
|
+
|
|
46
|
+
Remote paths inside a Linux Env remain POSIX (`/srv/...`). Local `env put`/`get`
|
|
47
|
+
on Windows accept Windows absolute paths (`C:\...`).
|
|
48
|
+
|
|
49
|
+
Local `exec` on Windows wraps Conda with `conda run` and venvs with
|
|
50
|
+
`Scripts\activate.bat` (remote Linux Nodes still use POSIX `sh`/`bash` wrappers).
|
|
51
|
+
If `ssh` is not on PATH, msdev looks in `%SystemRoot%\System32\OpenSSH\`.
|
|
52
|
+
|
|
26
53
|
## Nodes and execution environments
|
|
27
54
|
|
|
28
55
|
Register a host from `~/.ssh/config`:
|
|
@@ -83,6 +110,33 @@ msdev env add dev-122-vllm \
|
|
|
83
110
|
--layer venv:/srv/project/.venv
|
|
84
111
|
```
|
|
85
112
|
|
|
113
|
+
## File put, get, read, and write
|
|
114
|
+
|
|
115
|
+
Bulk transfer copies a local file into an Env filesystem, or fetches one back:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
msdev env put dev-122 ./config.yaml /srv/project/config.yaml
|
|
119
|
+
msdev env get dev-122 /srv/project/config.yaml --output ./config.yaml
|
|
120
|
+
msdev env get dev-122 /srv/project/config.yaml > ./config.yaml
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Editing uses content-oriented read/write. Paths inside the Env must be
|
|
124
|
+
absolute. Host Envs use direct filesystem copy locally and ``scp``/``ssh``
|
|
125
|
+
streams remotely. Docker Envs stage through the node with ``docker cp``.
|
|
126
|
+
File bytes never pass through JSON RPC.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
msdev env read dev-122 /srv/project/config.yaml
|
|
130
|
+
msdev env read dev-122 /srv/project/config.yaml --json
|
|
131
|
+
msdev env write dev-122 /srv/project/note.md --file /tmp/note.md
|
|
132
|
+
msdev env write dev-122 /srv/project/note.md < /tmp/note.md
|
|
133
|
+
msdev env write dev-122 /srv/project/note.md --file /tmp/note.md \
|
|
134
|
+
--expected-sha256 <digest>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Read before replacing an existing file. `--expected-sha256` is compare-and-swap
|
|
138
|
+
replacement that refuses to overwrite a changed remote file.
|
|
139
|
+
|
|
86
140
|
## NPU inventory
|
|
87
141
|
|
|
88
142
|
```bash
|
|
@@ -106,8 +160,8 @@ msdev exec \
|
|
|
106
160
|
-- python3 run.py
|
|
107
161
|
```
|
|
108
162
|
|
|
109
|
-
`--timeout-seconds` defaults to
|
|
110
|
-
|
|
163
|
+
`--timeout-seconds` defaults to `-1` (no deadline). Any positive finite duration
|
|
164
|
+
is also accepted. A positive timeout kills the complete command
|
|
111
165
|
process group and returns exit code 124. Cancelling the local CLI closes the RPC
|
|
112
166
|
connection, causing `msdevd` to kill and reap the remote process group. Finite
|
|
113
167
|
SSH/Unix RPC deadlines include a short completion grace for output drain and
|
|
@@ -116,66 +170,6 @@ serialization.
|
|
|
116
170
|
`--result-json` selects captured, non-streaming execution and prints one
|
|
117
171
|
structured JSON result containing stdout and stderr.
|
|
118
172
|
|
|
119
|
-
## Remote workspaces
|
|
120
|
-
|
|
121
|
-
A workspace gives a stable name to an Env and filesystem root:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
msdev workspace add project \
|
|
125
|
-
--env dev-122 \
|
|
126
|
-
--root /srv/project
|
|
127
|
-
|
|
128
|
-
msdev workspace list
|
|
129
|
-
msdev workspace inspect project
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Workspace operations are file- and Git-oriented. There is no
|
|
133
|
-
`msdev workspace exec`; use `msdev exec --env ... --cwd ...` for commands.
|
|
134
|
-
|
|
135
|
-
### Read and inspect
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
msdev workspace stat project README.md
|
|
139
|
-
msdev workspace read project README.md
|
|
140
|
-
msdev workspace read project weights.bin --output /tmp/weights.bin
|
|
141
|
-
msdev workspace list project src --json
|
|
142
|
-
msdev workspace glob project '**/*.py' --json
|
|
143
|
-
msdev workspace search project 'TODO' src tests --json
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Write safely
|
|
147
|
-
|
|
148
|
-
For non-trivial content, use stdin or `--file` rather than shell-escaped
|
|
149
|
-
`--content`:
|
|
150
|
-
|
|
151
|
-
```bash
|
|
152
|
-
msdev workspace write project docs/note.md < /tmp/note.md
|
|
153
|
-
msdev workspace write project docs/note.md --file /tmp/note.md
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Compare-and-swap replacement prevents overwriting a changed remote file:
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
msdev workspace apply-patch project docs/note.md \
|
|
160
|
-
--file /tmp/note.md \
|
|
161
|
-
--expected-sha256 <digest>
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Delete an explicit remote file:
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
msdev workspace delete project docs/obsolete.md
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Git
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
|
-
msdev workspace git-status project --result-json
|
|
174
|
-
msdev workspace git-diff project --result-json -- --stat
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Git diff rejects options that can write files or invoke external diff helpers.
|
|
178
|
-
|
|
179
173
|
## Model inventory
|
|
180
174
|
|
|
181
175
|
Examples:
|
|
@@ -192,59 +186,6 @@ msdev model audit --node dev-122
|
|
|
192
186
|
Use `msdev model --help` and the individual subcommand help for register,
|
|
193
187
|
update, replicas, refresh, verify, export, import, and rebind.
|
|
194
188
|
|
|
195
|
-
## Explicit CLI sessions and runbooks
|
|
196
|
-
|
|
197
|
-
Create a session before a reproducible workflow:
|
|
198
|
-
|
|
199
|
-
```bash
|
|
200
|
-
msdev session begin --name qwen3-quant --json
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Pass the returned ID explicitly or set it in a persistent terminal:
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
export MSDEV_SESSION_ID=<session-id>
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
Intent metadata is global and must appear before the subcommand:
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
msdev \
|
|
213
|
-
--session-id <session-id> \
|
|
214
|
-
--intent-kind execution \
|
|
215
|
-
--intent-summary 'Run Qwen3 quantization' \
|
|
216
|
-
--intent-phase quantization \
|
|
217
|
-
--intent-step-id quant-1 \
|
|
218
|
-
exec --env dev-122 --timeout-seconds 1800 -- python3 quant.py
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Intent kinds:
|
|
222
|
-
|
|
223
|
-
- `execution`: core reproduction step;
|
|
224
|
-
- `verification`: optional confirmation;
|
|
225
|
-
- `diagnostic`: troubleshooting, excluded from core steps;
|
|
226
|
-
- `exploration`: discovery, excluded from core steps.
|
|
227
|
-
|
|
228
|
-
Each invocation receives a unique `operation_id`. `session_id` groups CLI
|
|
229
|
-
operations only; it never supplies a Node, Env, or workspace default.
|
|
230
|
-
|
|
231
|
-
Logs are private JSONL files under:
|
|
232
|
-
|
|
233
|
-
```text
|
|
234
|
-
${XDG_STATE_HOME:-~/.local/state}/msdev/sessions/
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
They retain sanitized logical arguments, preview, explicit resource, intent,
|
|
238
|
-
exit code, and elapsed time. Command stdout/stderr and environment values are
|
|
239
|
-
not duplicated into logs.
|
|
240
|
-
|
|
241
|
-
```bash
|
|
242
|
-
msdev session list
|
|
243
|
-
msdev session export --session-id <session-id> --output runbook.md
|
|
244
|
-
msdev session export --latest --detail normal --output runbook.md
|
|
245
|
-
msdev session export --input /path/to/session.jsonl --detail full
|
|
246
|
-
```
|
|
247
|
-
|
|
248
189
|
## Architecture
|
|
249
190
|
|
|
250
191
|
```text
|
|
@@ -252,15 +193,18 @@ msdev CLI
|
|
|
252
193
|
-> typed core service
|
|
253
194
|
-> UnixRpcTransport or SshRpcTransport
|
|
254
195
|
-> per-user msdevd
|
|
255
|
-
-> host/container command,
|
|
196
|
+
-> host/container command, env file transfer, NPU, or inventory
|
|
256
197
|
```
|
|
257
198
|
|
|
258
|
-
Remote RPC responses and command output are bounded.
|
|
259
|
-
|
|
260
|
-
compare-and-swap. Node/Env and workspace registries use locked atomic updates.
|
|
199
|
+
Remote RPC responses and command output are bounded. Node/Env registries use
|
|
200
|
+
locked atomic updates.
|
|
261
201
|
|
|
262
202
|
## Testing
|
|
263
203
|
|
|
264
204
|
```bash
|
|
265
205
|
python3 -m unittest discover -s tests -v
|
|
266
206
|
```
|
|
207
|
+
|
|
208
|
+
Feature work must include at least one actual scenario test on the real
|
|
209
|
+
control path (`msdev` CLI → service → transport → `msdevd` → effect). Unit
|
|
210
|
+
tests alone are not sufficient.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "msdev"
|
|
7
|
-
version = "0.10.
|
|
7
|
+
version = "0.10.1"
|
|
8
8
|
description = "Portable nodes and execution environments for msModelSlim development"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -23,6 +23,7 @@ classifiers = [
|
|
|
23
23
|
"Programming Language :: Python :: 3.12",
|
|
24
24
|
"Programming Language :: Python :: 3.13",
|
|
25
25
|
"Operating System :: MacOS",
|
|
26
|
+
"Operating System :: Microsoft :: Windows",
|
|
26
27
|
"Operating System :: POSIX :: Linux",
|
|
27
28
|
"Topic :: Software Development :: Build Tools",
|
|
28
29
|
]
|