redeploy 0.2.78__tar.gz → 0.2.80__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.
- {redeploy-0.2.78/redeploy.egg-info → redeploy-0.2.80}/PKG-INFO +83 -14
- redeploy-0.2.78/PKG-INFO → redeploy-0.2.80/README.md +78 -37
- {redeploy-0.2.78 → redeploy-0.2.80}/pyproject.toml +21 -7
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/__init__.py +1 -1
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/binary.py +27 -2
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/reference.py +13 -1
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/executor.py +157 -21
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/handlers.py +174 -26
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/progress.py +25 -10
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/__init__.py +10 -0
- redeploy-0.2.80/redeploy/cli/commands/db_data.py +158 -0
- redeploy-0.2.80/redeploy/cli/commands/deploy_cmd.py +323 -0
- redeploy-0.2.80/redeploy/cli/commands/fleet_cmd.py +135 -0
- redeploy-0.2.80/redeploy/cli/commands/hash_cmd.py +61 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/plan_apply_run.py +29 -3
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/plan_apply_shared.py +2 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/run_cmd.py +39 -4
- redeploy-0.2.80/redeploy/cli/commands/sync_git.py +94 -0
- redeploy-0.2.80/redeploy/deploy_watch.py +264 -0
- redeploy-0.2.80/redeploy/detect/builtin/templates.yaml +215 -0
- redeploy-0.2.80/redeploy/fleet_ops.py +215 -0
- redeploy-0.2.80/redeploy/gitsync.py +380 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal/hint_provider.py +6 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal.py +7 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/mcp_server.py +175 -24
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/enums.py +4 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/plan.py +17 -0
- redeploy-0.2.80/redeploy/pg_sync.py +198 -0
- redeploy-0.2.80/redeploy/source_hash.py +170 -0
- redeploy-0.2.80/redeploy/templates/process_control_template.yaml +164 -0
- redeploy-0.2.78/README.md → redeploy-0.2.80/redeploy.egg-info/PKG-INFO +106 -7
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy.egg-info/SOURCES.txt +15 -45
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy.egg-info/requires.txt +4 -6
- redeploy-0.2.80/tests/test_gitsync_pg_hash.py +416 -0
- redeploy-0.2.80/tests/test_mcp_server.py +97 -0
- redeploy-0.2.80/tests/test_parallel_groups.py +252 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_prompt_llm.py +15 -5
- redeploy-0.2.78/redeploy/tests/__init__.py +0 -0
- redeploy-0.2.78/redeploy/tests/test_analyze.py +0 -193
- redeploy-0.2.78/redeploy/tests/test_audit.py +0 -244
- redeploy-0.2.78/redeploy/tests/test_cli.py +0 -328
- redeploy-0.2.78/redeploy/tests/test_data_sync.py +0 -117
- redeploy-0.2.78/redeploy/tests/test_devices_display.py +0 -33
- redeploy-0.2.78/redeploy/tests/test_discovery.py +0 -231
- redeploy-0.2.78/redeploy/tests/test_discovery_probe.py +0 -45
- redeploy-0.2.78/redeploy/tests/test_dsl.py +0 -354
- redeploy-0.2.78/redeploy/tests/test_examples.py +0 -518
- redeploy-0.2.78/redeploy/tests/test_executor.py +0 -732
- redeploy-0.2.78/redeploy/tests/test_fleet.py +0 -525
- redeploy-0.2.78/redeploy/tests/test_git_integration.py +0 -325
- redeploy-0.2.78/redeploy/tests/test_heal.py +0 -182
- redeploy-0.2.78/redeploy/tests/test_heal_decider.py +0 -91
- redeploy-0.2.78/redeploy/tests/test_hooks.py +0 -123
- redeploy-0.2.78/redeploy/tests/test_iac.py +0 -461
- redeploy-0.2.78/redeploy/tests/test_iac_compose_contract.py +0 -181
- redeploy-0.2.78/redeploy/tests/test_iac_docker_compose_contract.py +0 -172
- redeploy-0.2.78/redeploy/tests/test_manifest.py +0 -338
- redeploy-0.2.78/redeploy/tests/test_markpact_compiler.py +0 -147
- redeploy-0.2.78/redeploy/tests/test_markpact_parser.py +0 -93
- redeploy-0.2.78/redeploy/tests/test_models.py +0 -224
- redeploy-0.2.78/redeploy/tests/test_observe.py +0 -369
- redeploy-0.2.78/redeploy/tests/test_parse.py +0 -268
- redeploy-0.2.78/redeploy/tests/test_patterns.py +0 -287
- redeploy-0.2.78/redeploy/tests/test_plan_apply_report.py +0 -91
- redeploy-0.2.78/redeploy/tests/test_plan_apply_shared.py +0 -21
- redeploy-0.2.78/redeploy/tests/test_planner_edge.py +0 -350
- redeploy-0.2.78/redeploy/tests/test_plugins.py +0 -410
- redeploy-0.2.78/redeploy/tests/test_probes.py +0 -346
- redeploy-0.2.78/redeploy/tests/test_public_api.py +0 -243
- redeploy-0.2.78/redeploy/tests/test_resume.py +0 -271
- redeploy-0.2.78/redeploy/tests/test_security_hardening.py +0 -93
- redeploy-0.2.78/redeploy/tests/test_spec_loader.py +0 -105
- redeploy-0.2.78/redeploy/tests/test_ssh.py +0 -258
- redeploy-0.2.78/redeploy/tests/test_steps_registry.py +0 -109
- redeploy-0.2.78/redeploy/tests/test_templates.py +0 -429
- redeploy-0.2.78/redeploy/tests/test_verify.py +0 -218
- redeploy-0.2.78/redeploy/tests/test_version.py +0 -219
- redeploy-0.2.78/redeploy/tests/test_version_changelog.py +0 -356
- redeploy-0.2.78/redeploy/tests/test_version_cli.py +0 -887
- redeploy-0.2.78/redeploy/tests/test_version_manifest.py +0 -658
- redeploy-0.2.78/redeploy/tests/test_version_sources.py +0 -517
- redeploy-0.2.78/redeploy/tests/test_workflow.py +0 -286
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/base.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/command_ref.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/compose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/docker_build.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/env.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/checkers/path.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/ignore.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/models.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/preflight_schema.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/analyze/spec_analyzer.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/exceptions.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/rollback.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/state.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/state_apply.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/utils/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/apply/utils/run_container_build.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/auditor.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/extractor.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/models.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/paths.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/patterns.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/audit/probe.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/extractor.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/generators/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/generators/docker_compose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/generators/migration.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/sources/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/sources/compose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/sources/hardware.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/sources/infra.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/blueprint/sources/migration.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/apply_cmd.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/audit.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/blueprint.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/bump_fix.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/detect.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/device_map.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/device_map_actions.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/device_map_renderers.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/devices.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/devices_display.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/diagnose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/diff.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/exec_.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/export.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/gh_workflow.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/hardware.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/import_.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/init.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/inspect.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/lint.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/mcp_cmd.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/migrate_cmd.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/patterns.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/plan_apply.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/plan_apply_report.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/plan_cmd.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/plugin.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/probe.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/probe_display.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/prompt_cmd.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/push.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/state.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/status.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/target.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/commands.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/helpers.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/monorepo.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/release.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/scanner.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/utils/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/utils/changelog_config.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/version/utils/git_config.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/commands/workflow.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/core.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/display.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli/query.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/cli.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/config_apply/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/config_apply/applier.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/config_apply/handlers/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/config_apply/handlers/display.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/config_apply/loader.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/data_sync.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/builtin/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/detector.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/hardware.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/hardware_rules.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/probes.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/remote.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/templates.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/detect/workflow.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/auto_probe.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/helpers.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/probe_parse.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/registry.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/scanners.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/ssh_credentials.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/discovery/types.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl/loader.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl/parser.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/context.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/decorators.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/docker_steps.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/exceptions.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/runner.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/dsl_python/steps.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/fleet.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/config_txt.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/data/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/data/hyperpixel.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/data/official.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/data/waveshare.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/fixes.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/kiosk/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/kiosk/autostart.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/kiosk/browsers.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/kiosk/compositors.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/kiosk/output_profiles.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/panels.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/hardware/raspi_config.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal/decider.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal/log_writer.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal/loop_detector.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/heal/runner.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/base.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/config_hints.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/docker_compose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/parsers/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/parsers/compose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/iac/registry.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/integrations/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/integrations/op3_bridge.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/markpact/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/markpact/compiler.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/markpact/models.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/markpact/parser.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/blueprint.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/devices.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/hardware.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/infra.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/manifest.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/persisted.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/pipeline.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/models/spec.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/observe.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/parse.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/patterns.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plan/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plan/planner.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/builtin/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/builtin/browser_reload.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/builtin/hardware_diagnostic.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/builtin/notify.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/builtin/process_control.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/plugins/builtin/systemd_reload.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/schema.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/spec_loader.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/ssh.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/docker.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/generic.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/hardware.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/k3s.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/kiosk.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/podman.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/process.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/scm.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/steps/transfer.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/verify.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/bump.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/changelog.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/commits.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/diff.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/git_integration.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/git_transaction.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/manifest.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/__init__.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/base.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/json_.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/plain.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/regex.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/toml_.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/sources/yaml_.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version/transaction.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy/version.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy.egg-info/dependency_links.txt +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy.egg-info/entry_points.txt +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/redeploy.egg-info/top_level.txt +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/setup.cfg +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_blueprint_sources.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_blueprint_sources_compose.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_cli_gh_workflow.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_cli_query.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_example_argocd_flux_plugin.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_example_gitops_ci_plugin.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_example_helm_kustomize_plugin.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_hardware_config.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_hardware_kiosk.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_hardware_rules.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_heal_decider.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_heal_loop_detector.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_iac.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_iac_config_hints.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_iac_plugin_loading.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_import_plugin_template.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_parse.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_redeploy.py +0 -0
- {redeploy-0.2.78 → redeploy-0.2.80}/tests/test_steps_kiosk.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.80
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -14,15 +14,13 @@ Requires-Dist: paramiko>=3.0
|
|
|
14
14
|
Requires-Dist: httpx>=0.25
|
|
15
15
|
Requires-Dist: rich>=13.0
|
|
16
16
|
Requires-Dist: jmespath>=1.0
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist: pfix>=0.1.60
|
|
17
|
+
Requires-Dist: costs>=0.2.0
|
|
18
|
+
Requires-Dist: pfix>=0.1.79
|
|
20
19
|
Provides-Extra: dev
|
|
21
20
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
22
21
|
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
22
|
+
Requires-Dist: costs>=0.2.0; extra == "dev"
|
|
23
|
+
Requires-Dist: pfix>=0.1.79; extra == "dev"
|
|
26
24
|
Provides-Extra: op3
|
|
27
25
|
Requires-Dist: op3>=0.1.8; extra == "op3"
|
|
28
26
|
Provides-Extra: mcp
|
|
@@ -33,17 +31,17 @@ Requires-Dist: mcp>=1.0; extra == "mcp"
|
|
|
33
31
|
|
|
34
32
|
## AI Cost Tracking
|
|
35
33
|
|
|
36
|
-
    
|
|
35
|
+
  
|
|
38
36
|
|
|
39
|
-
- 🤖 **LLM usage:** $
|
|
40
|
-
- 👤 **Human dev:** ~$
|
|
37
|
+
- 🤖 **LLM usage:** $1.8574 (124 commits)
|
|
38
|
+
- 👤 **Human dev:** ~$5861 (58.6h @ $100/h, 30min dedup)
|
|
41
39
|
|
|
42
|
-
Generated on 2026-
|
|
40
|
+
Generated on 2026-09-06 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
43
41
|
|
|
44
42
|
---
|
|
45
43
|
|
|
46
|
-
    
|
|
47
45
|
|
|
48
46
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
49
47
|
|
|
@@ -111,6 +109,24 @@ redeploy run migration.yaml --detect
|
|
|
111
109
|
redeploy run migration.yaml
|
|
112
110
|
```
|
|
113
111
|
|
|
112
|
+
## Safe post-deploy verification
|
|
113
|
+
|
|
114
|
+
Steps roll back completed actions on failure by default. A post-deploy check
|
|
115
|
+
can fail the run without undoing an otherwise healthy deployment:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
extra_steps:
|
|
119
|
+
- id: smoke_after_commit
|
|
120
|
+
action: testql
|
|
121
|
+
query_source: tests/smoke.testql.toon.yaml
|
|
122
|
+
url: https://example.test
|
|
123
|
+
rollback_on_failure: false
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`redeploy run SPEC --plan-only` evaluates lint and preflight locally without
|
|
127
|
+
contacting the target or writing generated state. Use
|
|
128
|
+
`--preflight-schema-out PATH` when a persisted planning artifact is required.
|
|
129
|
+
|
|
114
130
|
## Quick start — Raspberry Pi kiosk
|
|
115
131
|
|
|
116
132
|
```bash
|
|
@@ -509,6 +525,57 @@ extra_steps:
|
|
|
509
525
|
insert_before: docker_build_pull # runs before build, not after verify
|
|
510
526
|
```
|
|
511
527
|
|
|
528
|
+
## Query-language post-deploy tests — `testql` / `oql` / `aql`
|
|
529
|
+
|
|
530
|
+
Beyond `http_check`/`inline_script`, redeploy can run **query-language test
|
|
531
|
+
scenarios** as post-deploy verification. Each runs the interpreter **locally**
|
|
532
|
+
(on the controller, where it is installed) and targets the freshly deployed
|
|
533
|
+
host via `url`. The step fails — and thus the deploy fails/rolls back — when the
|
|
534
|
+
scenario fails.
|
|
535
|
+
|
|
536
|
+
| Action | Default runner | Verdict | Purpose |
|
|
537
|
+
|--------|----------------|---------|---------|
|
|
538
|
+
| `testql` | `testql run --url <url> <file>` | exit 0 (+ optional `expect` in output) | API/GUI smoke of the deployed app |
|
|
539
|
+
| `oql` | `oqlctl <file> -m <mode> --json [--firmware-url <url>]` | JSON `ok == true` (fallback: exit 0) | run an OQL scenario against the deployed runtime/firmware |
|
|
540
|
+
| `aql` | `aql <file> [locale]` | exit 0 (+ optional `expect`, e.g. a variant name) | evaluate an AQL decision model and assert the verdict |
|
|
541
|
+
|
|
542
|
+
Fields (on top of `url` / `expect`):
|
|
543
|
+
|
|
544
|
+
- `query_source` — path to the `.testql.toon.yaml` / `.oql` / `.aql` scenario.
|
|
545
|
+
- `query_mode` — OQL mode: `validate` \| `dry-run` \| `execute`.
|
|
546
|
+
- `query_runner` — override the runner binary (absolute path is fine).
|
|
547
|
+
- `query_locale` — AQL locale (`en` \| `pl`).
|
|
548
|
+
- `query_context` — AQL: path to a context JSON for resolve.
|
|
549
|
+
- `command` — full command-template override; placeholders `{url} {source} {mode} {locale} {context}` are substituted (literal `{}` in the command are left intact — no `str.format`).
|
|
550
|
+
|
|
551
|
+
```yaml
|
|
552
|
+
extra_steps:
|
|
553
|
+
- id: post_deploy_oql
|
|
554
|
+
action: oql
|
|
555
|
+
description: "OQL: real sensor read from the deployed firmware"
|
|
556
|
+
query_source: deploy-tests/oql/firmware-sensor-read.oql
|
|
557
|
+
query_mode: execute
|
|
558
|
+
url: http://192.168.188.122:8202 # oqlctl --firmware-url
|
|
559
|
+
|
|
560
|
+
- id: post_deploy_testql
|
|
561
|
+
action: testql
|
|
562
|
+
description: "TestQL: API smoke of the deployed app"
|
|
563
|
+
query_source: deploy-tests/testql/post-deploy-api-smoke.testql.toon.yaml
|
|
564
|
+
flags: ["--output", "json", "--quiet"]
|
|
565
|
+
url: http://192.168.188.109:8100 # testql run --url
|
|
566
|
+
|
|
567
|
+
- id: post_deploy_aql
|
|
568
|
+
action: aql
|
|
569
|
+
description: "AQL: decision model returns the expected variant"
|
|
570
|
+
query_source: deploy-tests/aql/personalization.en.aql
|
|
571
|
+
command: "python3 /path/to/aql/cli.py {source} {locale}"
|
|
572
|
+
query_locale: en
|
|
573
|
+
expect: technical_deep
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
A ready example spec lives in c2004: `deploy-tests/post-deploy.redeploy.md`
|
|
577
|
+
(run with `redeploy run deploy-tests/post-deploy.redeploy.md`).
|
|
578
|
+
|
|
512
579
|
## Plugin system
|
|
513
580
|
|
|
514
581
|
Extend the step pipeline with custom action types using `action: plugin`:
|
|
@@ -934,7 +1001,9 @@ Language is auto-detected — Polish, English, or any language the model support
|
|
|
934
1001
|
|
|
935
1002
|
redeploy exposes an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server,
|
|
936
1003
|
letting AI assistants (Claude Desktop, VS Code Copilot, custom agents) call redeploy operations
|
|
937
|
-
as structured tools.
|
|
1004
|
+
as structured tools. Planning is enabled by default. Deployment, version, generated-command, and SSH
|
|
1005
|
+
mutations require the server-side capability `REDEPLOY_MCP_ALLOW_APPLY=1`, an
|
|
1006
|
+
`actor`, and the exact `approval_hash` returned for that operation.
|
|
938
1007
|
|
|
939
1008
|
### Start
|
|
940
1009
|
|
|
@@ -1,49 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: redeploy
|
|
3
|
-
Version: 0.2.78
|
|
4
|
-
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
|
-
License-Expression: Apache-2.0
|
|
6
|
-
Requires-Python: >=3.11
|
|
7
|
-
Description-Content-Type: text/markdown
|
|
8
|
-
Requires-Dist: pydantic>=2.0
|
|
9
|
-
Requires-Dist: pyyaml>=6.0
|
|
10
|
-
Requires-Dist: markdown-it-py>=3.0
|
|
11
|
-
Requires-Dist: click>=8.0
|
|
12
|
-
Requires-Dist: loguru>=0.7
|
|
13
|
-
Requires-Dist: paramiko>=3.0
|
|
14
|
-
Requires-Dist: httpx>=0.25
|
|
15
|
-
Requires-Dist: rich>=13.0
|
|
16
|
-
Requires-Dist: jmespath>=1.0
|
|
17
|
-
Requires-Dist: goal>=2.1.0
|
|
18
|
-
Requires-Dist: costs>=0.1.20
|
|
19
|
-
Requires-Dist: pfix>=0.1.60
|
|
20
|
-
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
22
|
-
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
23
|
-
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
24
|
-
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
25
|
-
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
26
|
-
Provides-Extra: op3
|
|
27
|
-
Requires-Dist: op3>=0.1.8; extra == "op3"
|
|
28
|
-
Provides-Extra: mcp
|
|
29
|
-
Requires-Dist: mcp>=1.0; extra == "mcp"
|
|
30
|
-
|
|
31
1
|
# redeploy
|
|
32
2
|
|
|
33
3
|
|
|
34
4
|
## AI Cost Tracking
|
|
35
5
|
|
|
36
|
-
    
|
|
7
|
+
  
|
|
38
8
|
|
|
39
|
-
- 🤖 **LLM usage:** $
|
|
40
|
-
- 👤 **Human dev:** ~$
|
|
9
|
+
- 🤖 **LLM usage:** $1.8574 (124 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$5861 (58.6h @ $100/h, 30min dedup)
|
|
41
11
|
|
|
42
|
-
Generated on 2026-
|
|
12
|
+
Generated on 2026-09-06 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
43
13
|
|
|
44
14
|
---
|
|
45
15
|
|
|
46
|
-
    
|
|
47
17
|
|
|
48
18
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
49
19
|
|
|
@@ -111,6 +81,24 @@ redeploy run migration.yaml --detect
|
|
|
111
81
|
redeploy run migration.yaml
|
|
112
82
|
```
|
|
113
83
|
|
|
84
|
+
## Safe post-deploy verification
|
|
85
|
+
|
|
86
|
+
Steps roll back completed actions on failure by default. A post-deploy check
|
|
87
|
+
can fail the run without undoing an otherwise healthy deployment:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
extra_steps:
|
|
91
|
+
- id: smoke_after_commit
|
|
92
|
+
action: testql
|
|
93
|
+
query_source: tests/smoke.testql.toon.yaml
|
|
94
|
+
url: https://example.test
|
|
95
|
+
rollback_on_failure: false
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`redeploy run SPEC --plan-only` evaluates lint and preflight locally without
|
|
99
|
+
contacting the target or writing generated state. Use
|
|
100
|
+
`--preflight-schema-out PATH` when a persisted planning artifact is required.
|
|
101
|
+
|
|
114
102
|
## Quick start — Raspberry Pi kiosk
|
|
115
103
|
|
|
116
104
|
```bash
|
|
@@ -509,6 +497,57 @@ extra_steps:
|
|
|
509
497
|
insert_before: docker_build_pull # runs before build, not after verify
|
|
510
498
|
```
|
|
511
499
|
|
|
500
|
+
## Query-language post-deploy tests — `testql` / `oql` / `aql`
|
|
501
|
+
|
|
502
|
+
Beyond `http_check`/`inline_script`, redeploy can run **query-language test
|
|
503
|
+
scenarios** as post-deploy verification. Each runs the interpreter **locally**
|
|
504
|
+
(on the controller, where it is installed) and targets the freshly deployed
|
|
505
|
+
host via `url`. The step fails — and thus the deploy fails/rolls back — when the
|
|
506
|
+
scenario fails.
|
|
507
|
+
|
|
508
|
+
| Action | Default runner | Verdict | Purpose |
|
|
509
|
+
|--------|----------------|---------|---------|
|
|
510
|
+
| `testql` | `testql run --url <url> <file>` | exit 0 (+ optional `expect` in output) | API/GUI smoke of the deployed app |
|
|
511
|
+
| `oql` | `oqlctl <file> -m <mode> --json [--firmware-url <url>]` | JSON `ok == true` (fallback: exit 0) | run an OQL scenario against the deployed runtime/firmware |
|
|
512
|
+
| `aql` | `aql <file> [locale]` | exit 0 (+ optional `expect`, e.g. a variant name) | evaluate an AQL decision model and assert the verdict |
|
|
513
|
+
|
|
514
|
+
Fields (on top of `url` / `expect`):
|
|
515
|
+
|
|
516
|
+
- `query_source` — path to the `.testql.toon.yaml` / `.oql` / `.aql` scenario.
|
|
517
|
+
- `query_mode` — OQL mode: `validate` \| `dry-run` \| `execute`.
|
|
518
|
+
- `query_runner` — override the runner binary (absolute path is fine).
|
|
519
|
+
- `query_locale` — AQL locale (`en` \| `pl`).
|
|
520
|
+
- `query_context` — AQL: path to a context JSON for resolve.
|
|
521
|
+
- `command` — full command-template override; placeholders `{url} {source} {mode} {locale} {context}` are substituted (literal `{}` in the command are left intact — no `str.format`).
|
|
522
|
+
|
|
523
|
+
```yaml
|
|
524
|
+
extra_steps:
|
|
525
|
+
- id: post_deploy_oql
|
|
526
|
+
action: oql
|
|
527
|
+
description: "OQL: real sensor read from the deployed firmware"
|
|
528
|
+
query_source: deploy-tests/oql/firmware-sensor-read.oql
|
|
529
|
+
query_mode: execute
|
|
530
|
+
url: http://192.168.188.122:8202 # oqlctl --firmware-url
|
|
531
|
+
|
|
532
|
+
- id: post_deploy_testql
|
|
533
|
+
action: testql
|
|
534
|
+
description: "TestQL: API smoke of the deployed app"
|
|
535
|
+
query_source: deploy-tests/testql/post-deploy-api-smoke.testql.toon.yaml
|
|
536
|
+
flags: ["--output", "json", "--quiet"]
|
|
537
|
+
url: http://192.168.188.109:8100 # testql run --url
|
|
538
|
+
|
|
539
|
+
- id: post_deploy_aql
|
|
540
|
+
action: aql
|
|
541
|
+
description: "AQL: decision model returns the expected variant"
|
|
542
|
+
query_source: deploy-tests/aql/personalization.en.aql
|
|
543
|
+
command: "python3 /path/to/aql/cli.py {source} {locale}"
|
|
544
|
+
query_locale: en
|
|
545
|
+
expect: technical_deep
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
A ready example spec lives in c2004: `deploy-tests/post-deploy.redeploy.md`
|
|
549
|
+
(run with `redeploy run deploy-tests/post-deploy.redeploy.md`).
|
|
550
|
+
|
|
512
551
|
## Plugin system
|
|
513
552
|
|
|
514
553
|
Extend the step pipeline with custom action types using `action: plugin`:
|
|
@@ -934,7 +973,9 @@ Language is auto-detected — Polish, English, or any language the model support
|
|
|
934
973
|
|
|
935
974
|
redeploy exposes an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server,
|
|
936
975
|
letting AI assistants (Claude Desktop, VS Code Copilot, custom agents) call redeploy operations
|
|
937
|
-
as structured tools.
|
|
976
|
+
as structured tools. Planning is enabled by default. Deployment, version, generated-command, and SSH
|
|
977
|
+
mutations require the server-side capability `REDEPLOY_MCP_ALLOW_APPLY=1`, an
|
|
978
|
+
`actor`, and the exact `approval_hash` returned for that operation.
|
|
938
979
|
|
|
939
980
|
### Start
|
|
940
981
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "redeploy"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.80"
|
|
8
8
|
description = "Infrastructure migration toolkit: detect → plan → apply"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -18,9 +18,8 @@ dependencies = [
|
|
|
18
18
|
"httpx>=0.25",
|
|
19
19
|
"rich>=13.0",
|
|
20
20
|
"jmespath>=1.0",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"pfix>=0.1.60",
|
|
21
|
+
"costs>=0.2.0",
|
|
22
|
+
"pfix>=0.1.79",
|
|
24
23
|
]
|
|
25
24
|
license = "Apache-2.0"
|
|
26
25
|
|
|
@@ -30,9 +29,8 @@ redeploy-mcp = "redeploy.mcp_server:serve"
|
|
|
30
29
|
|
|
31
30
|
[project.optional-dependencies]
|
|
32
31
|
dev = ["pytest>=8.0", "ruff>=0.4",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"pfix>=0.1.60",
|
|
32
|
+
"costs>=0.2.0",
|
|
33
|
+
"pfix>=0.1.79",
|
|
36
34
|
]
|
|
37
35
|
op3 = ["op3>=0.1.8"]
|
|
38
36
|
mcp = ["mcp>=1.0"]
|
|
@@ -40,9 +38,19 @@ mcp = ["mcp>=1.0"]
|
|
|
40
38
|
[tool.ruff]
|
|
41
39
|
line-length = 100
|
|
42
40
|
|
|
41
|
+
[tool.setuptools]
|
|
42
|
+
include-package-data = false
|
|
43
|
+
|
|
43
44
|
[tool.setuptools.packages.find]
|
|
44
45
|
where = ["."]
|
|
45
46
|
include = ["redeploy*"]
|
|
47
|
+
exclude = ["redeploy.tests*"]
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.package-data]
|
|
50
|
+
redeploy = ["**/*.yaml"]
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.exclude-package-data]
|
|
53
|
+
redeploy = ["tests/*", "tests/**/*"]
|
|
46
54
|
|
|
47
55
|
[tool.pfix]
|
|
48
56
|
# Self-healing Python configuration
|
|
@@ -72,3 +80,9 @@ max_commits = 500
|
|
|
72
80
|
|
|
73
81
|
# Cost thresholds for badge colors (USD)
|
|
74
82
|
badge_color_thresholds = { low = 1.0, medium = 5.0, high = 10.0, critical = 50.0 }
|
|
83
|
+
|
|
84
|
+
[dependency-groups]
|
|
85
|
+
automation = ["goal>=2.2.0"]
|
|
86
|
+
|
|
87
|
+
[tool.uv.dependency-groups.automation]
|
|
88
|
+
requires-python = ">=3.12"
|
|
@@ -7,7 +7,7 @@ Public API (stable from 0.2.0, semver guaranteed)::
|
|
|
7
7
|
|
|
8
8
|
Everything not listed in ``__all__`` is internal and may change without notice.
|
|
9
9
|
"""
|
|
10
|
-
__version__ = "0.2.
|
|
10
|
+
__version__ = "0.2.80"
|
|
11
11
|
|
|
12
12
|
# ── Core models ───────────────────────────────────────────────────────────────
|
|
13
13
|
from .models import ( # noqa: F401
|
|
@@ -5,15 +5,37 @@ import re
|
|
|
5
5
|
import shlex
|
|
6
6
|
import shutil
|
|
7
7
|
|
|
8
|
-
from ..models import
|
|
8
|
+
from ..models import IssueSeverity
|
|
9
9
|
from .base import Checker
|
|
10
10
|
|
|
11
11
|
_WRAPPERS = frozenset({"sudo", "env", "command", "nohup", "time", "exec"})
|
|
12
12
|
_KEYWORDS = frozenset({
|
|
13
13
|
"if", "then", "else", "fi", "for", "do", "done", "while", "case", "esac",
|
|
14
14
|
"function", "in", "until", "select", "echo", "true", "false", "test", "[", "[[",
|
|
15
|
+
"break", "continue", "return", "exit", "shift", "read", "printf", "cd", "pwd",
|
|
16
|
+
"export", "readonly", "local", "declare", "typeset", "unset", "set", "source", ".",
|
|
17
|
+
"alias", "unalias", "trap", "wait", "jobs", "fg", "bg", "getopts", "hash",
|
|
15
18
|
})
|
|
16
19
|
_SEPARATORS = frozenset({"&&", "||", "|", ";", "(", ")", "{", "}"})
|
|
20
|
+
_REMOTE_ACTIONS = frozenset({
|
|
21
|
+
"ssh_cmd",
|
|
22
|
+
"inline_script",
|
|
23
|
+
"systemctl_stop",
|
|
24
|
+
"systemctl_disable",
|
|
25
|
+
"systemctl_start",
|
|
26
|
+
"kubectl_delete",
|
|
27
|
+
"docker_compose_up",
|
|
28
|
+
"docker_compose_down",
|
|
29
|
+
"docker_build",
|
|
30
|
+
"docker_health_wait",
|
|
31
|
+
"container_log_tail",
|
|
32
|
+
"podman_build",
|
|
33
|
+
"ensure_config_line",
|
|
34
|
+
"raspi_config",
|
|
35
|
+
"ensure_kanshi_profile",
|
|
36
|
+
"ensure_autostart_entry",
|
|
37
|
+
"ensure_browser_kiosk_script",
|
|
38
|
+
})
|
|
17
39
|
|
|
18
40
|
|
|
19
41
|
def extract_binaries(cmd: str) -> list[str]:
|
|
@@ -57,7 +79,10 @@ class BinaryChecker(Checker):
|
|
|
57
79
|
def check(self, spec, document, base_dir, result):
|
|
58
80
|
for step in spec.extra_steps:
|
|
59
81
|
action = str(step.get("action") or "")
|
|
60
|
-
|
|
82
|
+
# Commands for these actions execute on the deployment target.
|
|
83
|
+
# Checking them with shutil.which() on the controller produces
|
|
84
|
+
# false warnings and says nothing about target availability.
|
|
85
|
+
if action in _REMOTE_ACTIONS:
|
|
61
86
|
continue
|
|
62
87
|
cmd = step.get("command") or ""
|
|
63
88
|
for binary in extract_binaries(cmd):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Reference integrity checkers for migration specs."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
-
from ..models import
|
|
4
|
+
from ..models import IssueSeverity
|
|
5
5
|
from .base import Checker
|
|
6
6
|
|
|
7
7
|
|
|
@@ -13,6 +13,18 @@ class ReferenceChecker(Checker):
|
|
|
13
13
|
|
|
14
14
|
step_ids = {s.get("id") for s in spec.extra_steps if s.get("id")}
|
|
15
15
|
step_ids |= set(StepLibrary.list())
|
|
16
|
+
# Strategy steps (for example install_quadlet_files or
|
|
17
|
+
# stop_<app>) are generated by Planner at runtime and are valid
|
|
18
|
+
# insertion anchors even though they are absent from extra_steps.
|
|
19
|
+
try:
|
|
20
|
+
from ...plan import Planner
|
|
21
|
+
|
|
22
|
+
generated = Planner.from_spec(spec).run()
|
|
23
|
+
step_ids |= {step.id for step in generated.steps}
|
|
24
|
+
except Exception:
|
|
25
|
+
# The remaining analyzers report malformed specs. Reference
|
|
26
|
+
# checking stays best-effort and must not mask their diagnostics.
|
|
27
|
+
pass
|
|
16
28
|
ref_ids: set[str] = set()
|
|
17
29
|
if document:
|
|
18
30
|
for block in document.blocks:
|