Metadata-Version: 2.4
Name: msdev
Version: 0.10.0
Summary: Portable nodes and execution environments for msModelSlim development
Author: msModelSlim Agent Contributors
License-Expression: MulanPSL-2.0
Project-URL: Homepage, https://gitcode.com/rookie_hongchuan/msdev
Project-URL: Repository, https://gitcode.com/rookie_hongchuan/msdev
Keywords: ssh,docker,conda,venv,remote,npu,mlops,devops
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# msdev

`msdev` manages connection Nodes and execution Envs. A Node owns SSH and its
per-user `msdevd`; an Env references a Node and adds a host/Docker runtime plus
optional conda/venv/uv layers.

The CLI is intentionally stateless:

- Node-scoped NPU/model operations name `--node` or use `--all`;
- execution names `--env`;
- every workspace operation names the registered workspace;
- no harness conversation binding or implicit current Env exists;
- MCP is not part of the architecture.

## Install

```bash
git clone https://gitcode.com/rookie_hongchuan/msdev.git
cd msdev
python3 -m pip install -e .
msdev --help
```

The package installs `msdev` and `msdevd`.

## Nodes and execution environments

Register a host from `~/.ssh/config`:

```bash
msdev node add dev-122 --ssh-host dev-122
msdev node list
msdev node status dev-122
```

Adding a Node atomically creates a same-named host Env. Bootstrap or refresh
the remote user daemon:

```bash
msdev node bootstrap dev-122
```

Persistent OpenSSH masters are optional:

```bash
msdev node connect dev-122
msdev node disconnect dev-122
```

Nodes and Envs have separate private Markdown guides:

```bash
msdev node guide dev-122
msdev node guide dev-122 --write ./dev-122-guide.md
msdev env guide dev-122
msdev env guide dev-122 --write ./host-env-guide.md
```

Guides are stored under `~/.config/msdev/guides/nodes/` and
`~/.config/msdev/guides/environments/`, with private permissions and a 256 KiB
limit. Agents read the applicable guides once before first use in a session.

Open a human-operated interactive shell in an Env:

```bash
msdev env shell dev-122
msdev env shell dev-122 --cwd /srv/project
```

The command allocates an OpenSSH PTY and enters the Env's Docker runtime and
conda/venv/uv layers. Exiting returns
to the local shell. Only the shell session start and final status are visible
to msdev; commands typed inside it are not individually logged. Agent
automation should continue using `msdev exec`.

Create another Env on the same Node for Docker and Python layers:

```bash
msdev env add dev-122-vllm \
  --node dev-122 \
  --docker-container vllm-ascend \
  --layer conda:base \
  --layer venv:/srv/project/.venv
```

## NPU inventory

```bash
msdev npu list --node dev-122 --json
msdev npu list --all --json
```

## Command execution

Commands execute synchronously and stream stdout and stderr to the terminal as
they are produced. Cursor or Claude Code should use their native background
terminal support for long jobs. Long jobs may also write a persistent progress
log when later inspection is required.

```bash
msdev exec \
  --env dev-122 \
  --cwd /srv/project \
  --timeout-seconds 1800 \
  --env-var MODE=test \
  -- python3 run.py
```

`--timeout-seconds` defaults to 300, accepts any positive finite duration, and
uses `-1` for no deadline. A positive timeout kills the complete command
process group and returns exit code 124. Cancelling the local CLI closes the RPC
connection, causing `msdevd` to kill and reap the remote process group. Finite
SSH/Unix RPC deadlines include a short completion grace for output drain and
serialization.

`--result-json` selects captured, non-streaming execution and prints one
structured JSON result containing stdout and stderr.

## Remote workspaces

A workspace gives a stable name to an Env and filesystem root:

```bash
msdev workspace add project \
  --env dev-122 \
  --root /srv/project

msdev workspace list
msdev workspace inspect project
```

Workspace operations are file- and Git-oriented. There is no
`msdev workspace exec`; use `msdev exec --env ... --cwd ...` for commands.

### Read and inspect

```bash
msdev workspace stat project README.md
msdev workspace read project README.md
msdev workspace read project weights.bin --output /tmp/weights.bin
msdev workspace list project src --json
msdev workspace glob project '**/*.py' --json
msdev workspace search project 'TODO' src tests --json
```

### Write safely

For non-trivial content, use stdin or `--file` rather than shell-escaped
`--content`:

```bash
msdev workspace write project docs/note.md < /tmp/note.md
msdev workspace write project docs/note.md --file /tmp/note.md
```

Compare-and-swap replacement prevents overwriting a changed remote file:

```bash
msdev workspace apply-patch project docs/note.md \
  --file /tmp/note.md \
  --expected-sha256 <digest>
```

Delete an explicit remote file:

```bash
msdev workspace delete project docs/obsolete.md
```

### Git

```bash
msdev workspace git-status project --result-json
msdev workspace git-diff project --result-json -- --stat
```

Git diff rejects options that can write files or invoke external diff helpers.

## Model inventory

Examples:

```bash
msdev model discover --node dev-122 --root /data/models
msdev model list --node dev-122 --json
msdev model list --all --json
msdev model inspect model://qwen/Qwen3-32B@main --node dev-122
msdev model validate model://qwen/Qwen3-32B@main --node dev-122
msdev model audit --node dev-122
```

Use `msdev model --help` and the individual subcommand help for register,
update, replicas, refresh, verify, export, import, and rebind.

## Explicit CLI sessions and runbooks

Create a session before a reproducible workflow:

```bash
msdev session begin --name qwen3-quant --json
```

Pass the returned ID explicitly or set it in a persistent terminal:

```bash
export MSDEV_SESSION_ID=<session-id>
```

Intent metadata is global and must appear before the subcommand:

```bash
msdev \
  --session-id <session-id> \
  --intent-kind execution \
  --intent-summary 'Run Qwen3 quantization' \
  --intent-phase quantization \
  --intent-step-id quant-1 \
  exec --env dev-122 --timeout-seconds 1800 -- python3 quant.py
```

Intent kinds:

- `execution`: core reproduction step;
- `verification`: optional confirmation;
- `diagnostic`: troubleshooting, excluded from core steps;
- `exploration`: discovery, excluded from core steps.

Each invocation receives a unique `operation_id`. `session_id` groups CLI
operations only; it never supplies a Node, Env, or workspace default.

Logs are private JSONL files under:

```text
${XDG_STATE_HOME:-~/.local/state}/msdev/sessions/
```

They retain sanitized logical arguments, preview, explicit resource, intent,
exit code, and elapsed time. Command stdout/stderr and environment values are
not duplicated into logs.

```bash
msdev session list
msdev session export --session-id <session-id> --output runbook.md
msdev session export --latest --detail normal --output runbook.md
msdev session export --input /path/to/session.jsonl --detail full
```

## Architecture

```text
msdev CLI
  -> typed core service
  -> UnixRpcTransport or SshRpcTransport
  -> per-user msdevd
  -> host/container command, workspace filesystem, NPU, or inventory
```

Remote RPC responses and command output are bounded. Workspace paths are
normalized under the registered root. Writes are atomic and support SHA-256
compare-and-swap. Node/Env and workspace registries use locked atomic updates.

## Testing

```bash
python3 -m unittest discover -s tests -v
```
