Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .containerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
*
!Containerfile
!environment-package-managers.json
!scripts/
!scripts/environment-package-manager-check.mjs
!dist/
!dist/driver.mjs
19 changes: 14 additions & 5 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ ARG ANTHROPIC_SDK_VERSION=0.111.0
ARG OPENAI_RUNTIME_VERSION=0.144.5
ARG OPENCODE_VERSION=1.18.4

# Environment package setup invokes `pip`, so the runtime image must provide it.
# Install the Python runtime behind writable pip package declarations.
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3-pip python-is-python3 \
&& rm -rf /var/lib/apt/lists/* \
&& python --version \
&& pip --version
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
python3 \
python3-pip \
python-is-python3 \
&& rm -rf /var/lib/apt/lists/*

COPY environment-package-managers.json /etc/mosoo/environment-package-managers.json
COPY scripts/environment-package-manager-check.mjs /usr/local/libexec/mosoo/environment-package-manager-check.mjs

# Environment writes expose only package managers verified by this image.
# Check executables, parseable versions, and runtime aliases here so capability
# failures surface while building the image rather than during a user Run.
RUN node /usr/local/libexec/mosoo/environment-package-manager-check.mjs verify

# Native agent CLIs pre-installed so the driver can spawn them via PATH.
# Installed in a single npm invocation to keep the agent packages in one layer.
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ vp run clean

`vp run build:image` uses Buildah to produce a local `agent-driver:local` OCI image and installs `dist/driver.mjs` on the image `PATH` as `agent-driver`.

The image contract in `environment-package-managers.json` exposes `npm` and `pip` to Mosoo Environment writes. The image build verifies that each tool is executable, reports a valid version, and resolves through coherent Python/pip aliases. `vp run docker:smoke:environment` installs and executes one pinned package through each manager using the same isolated-prefix mode as Mosoo Environment artifacts.

## Boundaries

- The Driver Kernel owns command dispatch, runtime event emission, provider lifecycle, permission flow, diagnostics, and host port contracts.
Expand All @@ -174,6 +176,7 @@ vp run clean

- `vp run check`
- `vp run build:image`
- `vp run docker:smoke:environment`
- no `@mosoo/*` runtime dependencies in `package.json`
- public entries include typed exports
- live artifact tests are gated by environment credentials
Expand Down
4 changes: 4 additions & 0 deletions environment-package-managers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"schemaVersion": 1,
"managers": ["npm", "pip"]
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"build": "vp run build:types && bun build src/bin/driver.ts --target bun --outfile dist/driver.mjs",
"build:types": "rm -rf dist/types && vp exec tsc -p tsconfig.types.json",
"build:image": "vp run build && buildah build -t agent-driver:local .",
"docker:smoke:environment": "docker run --rm --entrypoint node agent-driver:local /usr/local/libexec/mosoo/environment-package-manager-check.mjs smoke",
"check": "vp check && vp run tc && vp run test && vp run build",
"prepack": "vp run build"
},
Expand Down
194 changes: 194 additions & 0 deletions scripts/environment-package-manager-check.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { execFileSync } from "node:child_process";
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

const mode = process.argv[2] ?? "smoke";
const manifestPath =
process.env.MOSOO_ENVIRONMENT_PACKAGE_MANAGER_MANIFEST ??
"/etc/mosoo/environment-package-managers.json";
const SEMANTIC_VERSION = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/u;

function fail(message) {
console.error(message);
process.exit(1);
}

function readManifest() {
let manifest;
try {
manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
} catch (error) {
fail(
`Invalid Environment package-manager manifest: ${
error instanceof Error ? error.message : String(error)
}`,
);
}

if (manifest?.schemaVersion !== 1) {
fail("Invalid Environment package-manager manifest: schemaVersion must be 1");
}
if (!Array.isArray(manifest.managers) || manifest.managers.length === 0) {
fail("Invalid Environment package-manager manifest: managers must be a non-empty array");
}

const seen = new Set();
for (const manager of manifest.managers) {
if (typeof manager !== "string" || !/^[a-z][a-z0-9-]*$/.test(manager)) {
fail(`Invalid Environment package-manager manifest: invalid manager ${String(manager)}`);
}
if (seen.has(manager)) {
fail(`Invalid Environment package-manager manifest: duplicate manager ${manager}`);
}
seen.add(manager);
}

return manifest.managers;
}

function readCommandOutput(command, args, options = {}) {
try {
return execFileSync(command, args, { encoding: "utf8", ...options }).trim();
} catch (error) {
fail(`${command} failed: ${error instanceof Error ? error.message : String(error)}`);
}
}

function runCommand(command, args, options = {}) {
try {
execFileSync(command, args, { stdio: "inherit", ...options });
} catch (error) {
fail(`${command} failed: ${error instanceof Error ? error.message : String(error)}`);
}
}

function withTemporaryRoot(manager, callback) {
const root = mkdtempSync(join(tmpdir(), `mosoo-environment-${manager}-`));

try {
callback(root);
} finally {
rmSync(root, { force: true, recursive: true });
}
}

function assertExactVersion(tool, expected, actual) {
if (actual !== expected) {
fail(`${tool} version mismatch: expected ${expected}, got ${actual}`);
}
}

function assertSemanticVersion(tool, version) {
if (!SEMANTIC_VERSION.test(version)) {
fail(`${tool} returned an invalid version: ${version || "<empty>"}`);
}
return version;
}

function readSemanticVersion(tool, command, args, prefix = "") {
const output = readCommandOutput(command, args);
if (!output.startsWith(prefix)) {
fail(`${tool} returned an invalid version: ${output || "<empty>"}`);
}
return assertSemanticVersion(tool, output.slice(prefix.length));
}

function readPipVersion(tool, command, args) {
const output = readCommandOutput(command, args);
const match = /^pip (\S+) /u.exec(output);
return assertSemanticVersion(tool, match?.[1] ?? "");
}

function assertMatchingVersions(leftTool, leftVersion, rightTool, rightVersion) {
if (leftVersion !== rightVersion) {
fail(`${leftTool} and ${rightTool} versions do not match: ${leftVersion} != ${rightVersion}`);
}
}

const managerChecks = new Map([
[
"npm",
{
verify() {
const nodeVersion = readSemanticVersion("node", "node", ["--version"], "v");
const npmVersion = readSemanticVersion("npm", "npm", ["--version"]);
console.log(`Verified node ${nodeVersion} and npm ${npmVersion}.`);
},
smoke() {
withTemporaryRoot("npm", (root) => {
const npmRoot = join(root, "npm");
runCommand("npm", [
"install",
"--prefix",
npmRoot,
"--no-audit",
"--no-fund",
"--save-exact",
"prettier@3.3.3",
]);
assertExactVersion(
"prettier",
"3.3.3",
readCommandOutput(join(npmRoot, "node_modules", ".bin", "prettier"), ["--version"]),
);
});
},
},
],
[
"pip",
{
verify() {
const pythonVersion = readSemanticVersion("python", "python", ["--version"], "Python ");
const python3Version = readSemanticVersion("python3", "python3", ["--version"], "Python ");
assertMatchingVersions("python", pythonVersion, "python3", python3Version);

const pipVersion = readPipVersion("pip", "pip", ["--version"]);
const modulePipVersion = readPipVersion("python -m pip", "python", [
"-m",
"pip",
"--version",
]);
assertMatchingVersions("pip", pipVersion, "python -m pip", modulePipVersion);
console.log(`Verified python ${pythonVersion} and pip ${pipVersion}.`);
},
smoke() {
withTemporaryRoot("pip", (root) => {
const pipRoot = join(root, "python");
runCommand("python", [
"-m",
"pip",
"install",
"--disable-pip-version-check",
"--no-input",
"--ignore-installed",
"--prefix",
pipRoot,
"six==1.16.0",
]);
const pythonSite = readCommandOutput("python", [
"-c",
'import sys,sysconfig; p=sys.argv[1]; print(sysconfig.get_path("purelib",vars={"base":p,"platbase":p}))',
pipRoot,
]);
runCommand("python", ["-c", 'import six; assert six.__version__ == "1.16.0"'], {
env: { ...process.env, PYTHONPATH: pythonSite },
});
});
},
},
],
]);

if (mode !== "verify" && mode !== "smoke") {
fail(`Unsupported Environment package-manager check mode: ${mode}`);
}

for (const manager of readManifest()) {
const check = managerChecks.get(manager);
if (!check) {
fail(`Environment package manager has no ${mode} check: ${manager}`);
}
check[mode]();
}
22 changes: 21 additions & 1 deletion tests/driver-artifact-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ interface DriverPackageJson {
readonly version?: string;
}

interface EnvironmentPackageManagerManifest {
readonly managers?: readonly string[];
readonly schemaVersion?: number;
}

const PUBLIC_EXPORTS = [
".",
"./boot",
Expand All @@ -54,6 +59,12 @@ function readDriverPackageJson(): DriverPackageJson {
return JSON.parse(readText("../package.json")) as DriverPackageJson;
}

function readEnvironmentPackageManagerManifest(): EnvironmentPackageManagerManifest {
return JSON.parse(
readText("../environment-package-managers.json"),
) as EnvironmentPackageManagerManifest;
}

describe("driver artifact contract", () => {
test("uses the public mosoo package identity", () => {
const packageJson = readDriverPackageJson();
Expand Down Expand Up @@ -209,7 +220,16 @@ describe("driver artifact contract", () => {
expect(imageIndex).toBeGreaterThan(liveIndex);
});

test("keeps the standalone package out of mosoo workspace dependencies", () => {
test("declares writable Environment package managers", () => {
const manifest = readEnvironmentPackageManagerManifest();

expect(manifest).toEqual({
managers: ["npm", "pip"],
schemaVersion: 1,
});
});

test("keeps the standalone package out of Mosoo workspace dependencies", () => {
const packageJson = readDriverPackageJson();
const deps = Object.keys(packageJson.dependencies ?? {});
const tsconfig = readText("../tsconfig.json");
Expand Down