Turn the stable workspace surface into five documented, runnable stories with a shared guest-backed smoke runner, new docs/use-cases recipes, and Make targets for cold-start validation, repro/fix loops, parallel workspaces, untrusted inspection, and review/eval workflows. Bump the package and catalog surface to 3.6.0, update the main docs to point users from the stable workspace walkthrough into the recipe index and smoke packs, and mark the 3.6.0 roadmap milestone done. Fix a regression uncovered by the real parallel-workspaces smoke: workspace_file_read must not bump last_activity_at. Verified with uv lock, UV_CACHE_DIR=.uv-cache make check, UV_CACHE_DIR=.uv-cache make dist-check, and USE_CASE_ENVIRONMENT=debian:12 UV_CACHE_DIR=.uv-cache make smoke-use-cases.
203 lines
11 KiB
Makefile
203 lines
11 KiB
Makefile
PYTHON ?= uv run python
|
|
UV_CACHE_DIR ?= .uv-cache
|
|
OLLAMA_BASE_URL ?= http://localhost:11434/v1
|
|
OLLAMA_MODEL ?= llama3.2:3b
|
|
OLLAMA_DEMO_FLAGS ?=
|
|
RUNTIME_PLATFORM ?= linux-x86_64
|
|
RUNTIME_SOURCE_DIR ?= runtime_sources
|
|
RUNTIME_BUILD_DIR ?= build/runtime_bundle
|
|
RUNTIME_BUNDLE_DIR ?= src/pyro_mcp/runtime_bundle
|
|
RUNTIME_MATERIALIZED_DIR ?= build/runtime_sources
|
|
RUNTIME_OCI_LAYOUT_DIR ?= build/oci_layouts
|
|
RUNTIME_ENVIRONMENT ?= debian:12-base
|
|
RUNTIME_ENVIRONMENTS ?= debian:12-base debian:12 debian:12-build
|
|
PYPI_DIST_DIR ?= dist
|
|
TWINE_USERNAME ?= __token__
|
|
PYPI_REPOSITORY_URL ?=
|
|
USE_CASE_ENVIRONMENT ?= debian:12
|
|
USE_CASE_SMOKE_FLAGS ?=
|
|
|
|
.PHONY: help setup lint format typecheck test check dist-check pypi-publish demo network-demo doctor ollama ollama-demo run-server install-hooks smoke-use-cases smoke-cold-start-validation smoke-repro-fix-loop smoke-parallel-workspaces smoke-untrusted-inspection smoke-review-eval runtime-bundle runtime-binaries runtime-kernel runtime-rootfs runtime-agent runtime-validate runtime-manifest runtime-sync runtime-clean runtime-fetch-binaries runtime-build-kernel-real runtime-build-rootfs-real runtime-materialize runtime-export-environment-oci runtime-export-official-environments-oci runtime-publish-environment-oci runtime-publish-official-environments-oci runtime-boot-check runtime-network-check
|
|
|
|
help:
|
|
@printf '%s\n' \
|
|
'Available targets:' \
|
|
' help Show this help message' \
|
|
' setup Install project dependencies' \
|
|
' lint Run Ruff lint checks' \
|
|
' format Run Ruff formatter' \
|
|
' typecheck Run mypy' \
|
|
' test Run pytest' \
|
|
' check Run lint, typecheck, and tests' \
|
|
' dist-check Smoke-test the installed pyro CLI and environment UX' \
|
|
' pypi-publish Build, validate, and upload the package to PyPI' \
|
|
' demo Run the deterministic VM demo' \
|
|
' network-demo Run the deterministic VM demo with guest networking enabled' \
|
|
' doctor Show runtime and host diagnostics' \
|
|
' smoke-use-cases Run all real guest-backed workspace use-case smokes' \
|
|
' smoke-cold-start-validation Run the cold-start repo validation smoke' \
|
|
' smoke-repro-fix-loop Run the repro-plus-fix loop smoke' \
|
|
' smoke-parallel-workspaces Run the parallel isolated workspaces smoke' \
|
|
' smoke-untrusted-inspection Run the unsafe or untrusted inspection smoke' \
|
|
' smoke-review-eval Run the review and evaluation workflow smoke' \
|
|
' ollama-demo Run the network-enabled Ollama lifecycle demo' \
|
|
' run-server Run the MCP server' \
|
|
' install-hooks Install pre-commit hooks' \
|
|
' runtime-bundle Rebuild and sync the packaged runtime bundle' \
|
|
' runtime-binaries Stage runtime binaries into the build bundle' \
|
|
' runtime-kernel Stage kernel artifacts into the build bundle' \
|
|
' runtime-rootfs Stage rootfs artifacts into the build bundle' \
|
|
' runtime-agent Stage guest agent artifacts into the build bundle' \
|
|
' runtime-validate Validate runtime sources against the lockfile' \
|
|
' runtime-manifest Regenerate the runtime manifest in the build bundle' \
|
|
' runtime-sync Sync the built runtime bundle into src/' \
|
|
' runtime-fetch-binaries Materialize pinned upstream Firecracker binaries' \
|
|
' runtime-build-kernel-real Materialize the real guest kernel' \
|
|
' runtime-build-rootfs-real Materialize the real guest rootfs images' \
|
|
' runtime-materialize Run all real-source materialization steps' \
|
|
' runtime-export-environment-oci Export one environment as a local OCI layout' \
|
|
' runtime-export-official-environments-oci Export all official environments as OCI layouts' \
|
|
' runtime-publish-environment-oci Publish one exported OCI layout to its registry target' \
|
|
' runtime-publish-official-environments-oci Publish all official environments to their registry targets' \
|
|
' runtime-boot-check Validate direct Firecracker boot from the bundled runtime' \
|
|
' runtime-network-check Validate outbound guest networking from the bundled runtime' \
|
|
' runtime-clean Remove generated runtime build artifacts'
|
|
|
|
setup:
|
|
uv sync --dev
|
|
|
|
lint:
|
|
uv run ruff check .
|
|
|
|
format:
|
|
uv run ruff format .
|
|
|
|
typecheck:
|
|
uv run mypy
|
|
|
|
test:
|
|
uv run pytest
|
|
|
|
check: lint typecheck test
|
|
|
|
dist-check:
|
|
.venv/bin/pyro --version
|
|
.venv/bin/pyro --help >/dev/null
|
|
.venv/bin/pyro mcp --help >/dev/null
|
|
.venv/bin/pyro run --help >/dev/null
|
|
.venv/bin/pyro env list >/dev/null
|
|
.venv/bin/pyro env inspect debian:12 >/dev/null
|
|
.venv/bin/pyro doctor >/dev/null
|
|
|
|
pypi-publish:
|
|
@if [ -z "$$TWINE_PASSWORD" ]; then \
|
|
printf '%s\n' 'TWINE_PASSWORD is required; use a PyPI API token.' >&2; \
|
|
exit 1; \
|
|
fi
|
|
rm -rf "$(PYPI_DIST_DIR)"
|
|
uv build --out-dir "$(PYPI_DIST_DIR)"
|
|
uvx --from twine twine check "$(PYPI_DIST_DIR)"/*
|
|
@if [ -n "$(PYPI_REPOSITORY_URL)" ]; then \
|
|
TWINE_USERNAME="$(TWINE_USERNAME)" uvx --from twine twine upload --repository-url "$(PYPI_REPOSITORY_URL)" "$(PYPI_DIST_DIR)"/*; \
|
|
else \
|
|
TWINE_USERNAME="$(TWINE_USERNAME)" uvx --from twine twine upload "$(PYPI_DIST_DIR)"/*; \
|
|
fi
|
|
|
|
demo:
|
|
uv run pyro demo
|
|
|
|
network-demo:
|
|
uv run pyro demo --network
|
|
|
|
doctor:
|
|
uv run pyro doctor
|
|
|
|
smoke-use-cases:
|
|
uv run python scripts/workspace_use_case_smoke.py --scenario all --environment "$(USE_CASE_ENVIRONMENT)" $(USE_CASE_SMOKE_FLAGS)
|
|
|
|
smoke-cold-start-validation:
|
|
uv run python scripts/workspace_use_case_smoke.py --scenario cold-start-validation --environment "$(USE_CASE_ENVIRONMENT)" $(USE_CASE_SMOKE_FLAGS)
|
|
|
|
smoke-repro-fix-loop:
|
|
uv run python scripts/workspace_use_case_smoke.py --scenario repro-fix-loop --environment "$(USE_CASE_ENVIRONMENT)" $(USE_CASE_SMOKE_FLAGS)
|
|
|
|
smoke-parallel-workspaces:
|
|
uv run python scripts/workspace_use_case_smoke.py --scenario parallel-workspaces --environment "$(USE_CASE_ENVIRONMENT)" $(USE_CASE_SMOKE_FLAGS)
|
|
|
|
smoke-untrusted-inspection:
|
|
uv run python scripts/workspace_use_case_smoke.py --scenario untrusted-inspection --environment "$(USE_CASE_ENVIRONMENT)" $(USE_CASE_SMOKE_FLAGS)
|
|
|
|
smoke-review-eval:
|
|
uv run python scripts/workspace_use_case_smoke.py --scenario review-eval --environment "$(USE_CASE_ENVIRONMENT)" $(USE_CASE_SMOKE_FLAGS)
|
|
|
|
ollama: ollama-demo
|
|
|
|
ollama-demo:
|
|
uv run pyro demo ollama --base-url "$(OLLAMA_BASE_URL)" --model "$(OLLAMA_MODEL)" $(OLLAMA_DEMO_FLAGS)
|
|
|
|
run-server:
|
|
uv run pyro mcp serve
|
|
|
|
install-hooks:
|
|
uv run pre-commit install
|
|
|
|
runtime-binaries:
|
|
uv run python -m pyro_mcp.runtime_build stage-binaries --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-kernel:
|
|
uv run python -m pyro_mcp.runtime_build stage-kernel --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-rootfs:
|
|
uv run python -m pyro_mcp.runtime_build stage-rootfs --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-agent:
|
|
uv run python -m pyro_mcp.runtime_build stage-agent --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-validate:
|
|
uv run python -m pyro_mcp.runtime_build validate --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-manifest:
|
|
uv run python -m pyro_mcp.runtime_build manifest --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-sync:
|
|
uv run python -m pyro_mcp.runtime_build sync --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-bundle:
|
|
uv run python -m pyro_mcp.runtime_build bundle --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-fetch-binaries:
|
|
uv run python -m pyro_mcp.runtime_build fetch-binaries --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-build-kernel-real:
|
|
uv run python -m pyro_mcp.runtime_build build-kernel --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-build-rootfs-real:
|
|
uv run python -m pyro_mcp.runtime_build build-rootfs --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-materialize:
|
|
uv run python -m pyro_mcp.runtime_build materialize --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)"
|
|
|
|
runtime-export-environment-oci:
|
|
uv run python -m pyro_mcp.runtime_build export-environment-oci --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)" --environment "$(RUNTIME_ENVIRONMENT)" --output-dir "$(RUNTIME_OCI_LAYOUT_DIR)"
|
|
|
|
runtime-export-official-environments-oci:
|
|
@for environment in $(RUNTIME_ENVIRONMENTS); do \
|
|
$(MAKE) runtime-export-environment-oci RUNTIME_ENVIRONMENT="$$environment"; \
|
|
done
|
|
|
|
runtime-publish-environment-oci:
|
|
uv run python -m pyro_mcp.runtime_build publish-environment-oci --platform "$(RUNTIME_PLATFORM)" --source-dir "$(RUNTIME_SOURCE_DIR)" --build-dir "$(RUNTIME_BUILD_DIR)" --bundle-dir "$(RUNTIME_BUNDLE_DIR)" --materialized-dir "$(RUNTIME_MATERIALIZED_DIR)" --environment "$(RUNTIME_ENVIRONMENT)" --layout-root "$(RUNTIME_OCI_LAYOUT_DIR)"
|
|
|
|
runtime-publish-official-environments-oci:
|
|
@for environment in $(RUNTIME_ENVIRONMENTS); do \
|
|
$(MAKE) runtime-publish-environment-oci RUNTIME_ENVIRONMENT="$$environment"; \
|
|
done
|
|
|
|
runtime-boot-check:
|
|
uv run python -m pyro_mcp.runtime_boot_check
|
|
|
|
runtime-network-check:
|
|
uv run python -m pyro_mcp.runtime_network_check
|
|
|
|
runtime-clean:
|
|
rm -rf "$(RUNTIME_BUILD_DIR)" "$(RUNTIME_MATERIALIZED_DIR)"
|