feat: add project-composable DeepSeek Harness microVMs

Share the live project cwd, DSH home and skills read-write while running guest root behind rootless QEMU and Bubblewrap. Reuse project toolchains, expose configurable SSH-forwarded web access, and launch the latest official DSH.

Include the project template, operating guide, offline boot and mount tests, and shell checks.
This commit is contained in:
OpenAI Coding Assistant
2026-09-06 12:45:36 -05:00
parent 221e0b33cc
commit 35ca88d517
14 changed files with 1219 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
result
result-*
.env
.env.*
*.qcow2
*.img
+27
View File
@@ -0,0 +1,27 @@
# Project + DeepSeek Harness microVM
`project.nix` is the shared toolchain for `nix develop` and the guest.
`flake.nix` sets RAM, vCPUs and networking. Run from the project directory:
```sh
nix run .#agent # boots with cwd mounted read-write at its original path
# Another terminal in the same directory:
nix run .#agent -- url # private browser login URL
nix run .#agent -- ssh # root shell, starting in the same project cwd
nix run .#agent -- stop
```
`$DSH_HOME` (default `~/.dsh`) and `${DSH_AGENTS_HOME:-~/.agents}/skills` are
also mounted **read-write**. No other home directories or host sockets are shared.
The first run creates missing DSH/skills directories. Existing DSH home must be
private (`chmod 700 ~/.dsh`). Credentials, settings, profiles and skills are live
shared files, not copied into the Nix store. Select the project's original
absolute path in the DSH UI; `/workspace` is also an alias.
DSH resolves `@deepseek-ai/dsh@latest` inside the VM on startup. Nix packages
follow the rolling Nixpkgs input: `nix flake update`, then restart the VM.
See `/etc/nix/AGENT-VM.md` for the full guide and security boundaries. The reusable
input lives at `/etc/nix/agent-vm`; replace the local input with your Git remote
when sharing this project. Keep backups: the agent can modify/delete the mounted
project and its shared DSH configuration/credentials/skills.
+44
View File
@@ -0,0 +1,44 @@
{
description = "Project toolchain + DeepSeek Harness microVM";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# Local bootstrap. For teammates/CI use your Git remote's moving branch:
# git+https://YOUR-REMOTE/nixconfig.git?dir=agent-vm&ref=main
agent-vm.url = "path:/etc/nix/agent-vm";
agent-vm.inputs.nixpkgs.follows = "nixpkgs";
};
outputs =
{ nixpkgs, agent-vm, ... }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
project = import ./project.nix { inherit pkgs; };
agent = agent-vm.lib.mkAgentVM {
inherit system project;
modules = [
{
microvm.mem = 4096; # MiB
microvm.vcpu = 4;
agentVM.network = {
hostAddress = "127.0.0.1"; # Or a host LAN/VPN IPv4 address, or 0.0.0.0.
sshPort = 2222; # Always host localhost in user-network mode.
webPort = 3080;
# For 0.0.0.0, list the actual browser authorities, not a wildcard:
# trustedHosts = [ "192.168.1.20:3080" ];
};
}
];
};
in
{
devShells.${system}.default = pkgs.mkShell {
inherit (project) packages env;
};
packages.${system}.agent = agent.package;
apps.${system}.agent = agent.app;
nixosConfigurations.agent = agent.nixos;
formatter.${system} = pkgs.nixfmt;
};
}
+18
View File
@@ -0,0 +1,18 @@
{ pkgs }:
{
# Single source of truth: both pkgs.mkShell and the VM consume this attrset.
# Replace/add your project's pinned toolchain here, not in two separate lists.
packages = with pkgs; [
python3
uv
ruff
nodejs
pnpm
git
ripgrep
];
# Shared non-secret variables. Do not put API tokens in a Nix expression.
env = {
UV_PYTHON_DOWNLOADS = "never";
};
}