redeploy 0.2.31__tar.gz → 0.2.32__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.31 → redeploy-0.2.32}/PKG-INFO +6 -6
- {redeploy-0.2.31 → redeploy-0.2.32}/README.md +5 -5
- {redeploy-0.2.31 → redeploy-0.2.32}/pyproject.toml +1 -1
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/__init__.py +1 -1
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/models.py +86 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy.egg-info/PKG-INFO +6 -6
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/exceptions.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/executor.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/handlers.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/progress.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/rollback.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/apply/state.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/audit.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/audit.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/detect.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/devices.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/diagnose.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/diff.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/exec_.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/export.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/import_.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/init.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/inspect.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/patterns.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/plan_apply.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/plugin.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/probe.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/state.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/status.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/target.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/version.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/commands/workflow.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/core.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli/display.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/cli.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/data_sync.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/detect/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/detect/detector.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/detect/probes.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/detect/remote.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/detect/templates.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/detect/workflow.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/discovery.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl/loader.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl/parser.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/context.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/decorators.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/docker_steps.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/exceptions.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/runner.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/dsl_python/steps.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/fleet.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/iac/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/iac/base.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/iac/docker_compose.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/iac/parsers/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/iac/parsers/compose.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/iac/registry.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/markpact/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/markpact/compiler.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/markpact/models.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/markpact/parser.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/observe.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/parse.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/patterns.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plan/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plan/planner.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/builtin/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/builtin/browser_reload.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/builtin/hardware_diagnostic.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/builtin/notify.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/builtin/process_control.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/plugins/builtin/systemd_reload.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/spec_loader.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/ssh.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/steps.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_audit.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_cli.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_data_sync.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_discovery.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_dsl.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_examples.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_executor.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_fleet.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_git_integration.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_iac.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_manifest.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_markpact_compiler.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_markpact_parser.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_models.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_observe.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_parse.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_patterns.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_planner_edge.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_plugins.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_probes.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_public_api.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_resume.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_spec_loader.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_ssh.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_templates.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_verify.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_version.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_version_changelog.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_version_cli.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_version_manifest.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_version_sources.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/tests/test_workflow.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/verify.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/bump.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/changelog.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/commits.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/diff.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/git_integration.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/git_transaction.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/manifest.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/__init__.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/base.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/json_.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/plain.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/regex.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/toml_.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/sources/yaml_.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version/transaction.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy/version.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy.egg-info/SOURCES.txt +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy.egg-info/dependency_links.txt +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy.egg-info/entry_points.txt +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy.egg-info/requires.txt +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/redeploy.egg-info/top_level.txt +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/setup.cfg +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/tests/test_iac.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/tests/test_parse.py +0 -0
- {redeploy-0.2.31 → redeploy-0.2.32}/tests/test_redeploy.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.32
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -27,17 +27,17 @@ Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
|
27
27
|
|
|
28
28
|
## AI Cost Tracking
|
|
29
29
|
|
|
30
|
-
     
|
|
31
|
+
  
|
|
32
32
|
|
|
33
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
34
|
-
- 👤 **Human dev:** ~$
|
|
33
|
+
- 🤖 **LLM usage:** $7.5000 (52 commits)
|
|
34
|
+
- 👤 **Human dev:** ~$1755 (17.5h @ $100/h, 30min dedup)
|
|
35
35
|
|
|
36
36
|
Generated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
    
|
|
41
41
|
|
|
42
42
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
43
43
|
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
|
|
4
4
|
## AI Cost Tracking
|
|
5
5
|
|
|
6
|
-
     
|
|
7
|
+
  
|
|
8
8
|
|
|
9
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
10
|
-
- 👤 **Human dev:** ~$
|
|
9
|
+
- 🤖 **LLM usage:** $7.5000 (52 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$1755 (17.5h @ $100/h, 30min dedup)
|
|
11
11
|
|
|
12
12
|
Generated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
    
|
|
17
17
|
|
|
18
18
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
19
19
|
|
|
@@ -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.32"
|
|
11
11
|
|
|
12
12
|
# ── Core models ───────────────────────────────────────────────────────────────
|
|
13
13
|
from .models import ( # noqa: F401
|
|
@@ -120,6 +120,92 @@ class AppHealthInfo(BaseModel):
|
|
|
120
120
|
response_ms: Optional[float] = None
|
|
121
121
|
|
|
122
122
|
|
|
123
|
+
# ── Hardware (output of hardware probe) ───────────────────────────────────────
|
|
124
|
+
|
|
125
|
+
class DrmOutput(BaseModel):
|
|
126
|
+
"""One DRM connector (e.g. card1-DSI-2, card2-HDMI-A-1)."""
|
|
127
|
+
name: str # e.g. "card1-DSI-2"
|
|
128
|
+
connector: str # e.g. "DSI-2", "HDMI-A-1"
|
|
129
|
+
status: str = "unknown" # connected / disconnected
|
|
130
|
+
enabled: str = "unknown" # enabled / disabled
|
|
131
|
+
modes: list[str] = Field(default_factory=list) # e.g. ["1280x800@60"]
|
|
132
|
+
transform: str = "normal"
|
|
133
|
+
position: str = "0,0"
|
|
134
|
+
scale: str = "1.0"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class BacklightInfo(BaseModel):
|
|
138
|
+
"""Sysfs backlight device."""
|
|
139
|
+
name: str # e.g. "11-0045"
|
|
140
|
+
brightness: int = 0
|
|
141
|
+
max_brightness: int = 255
|
|
142
|
+
bl_power: int = 0 # 0=on, 4=off
|
|
143
|
+
display_name: Optional[str] = None # e.g. "DSI-2"
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class I2CBusInfo(BaseModel):
|
|
147
|
+
bus: int
|
|
148
|
+
devices: list[str] = Field(default_factory=list) # hex addresses found
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class HardwareDiagnostic(BaseModel):
|
|
152
|
+
"""Problem found during hardware probe."""
|
|
153
|
+
component: str # "dsi", "backlight", "i2c", "gpio", "overlay"
|
|
154
|
+
severity: str = "warning" # info / warning / error / critical
|
|
155
|
+
message: str
|
|
156
|
+
fix: Optional[str] = None # suggested fix command or action
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class HardwareInfo(BaseModel):
|
|
160
|
+
"""Hardware state produced by hardware probe."""
|
|
161
|
+
board: Optional[str] = None # e.g. "Raspberry Pi 5 Model B Rev 1.0"
|
|
162
|
+
kernel: Optional[str] = None # uname -r
|
|
163
|
+
config_txt: str = "" # full /boot/firmware/config.txt
|
|
164
|
+
|
|
165
|
+
# Display
|
|
166
|
+
drm_outputs: list[DrmOutput] = Field(default_factory=list)
|
|
167
|
+
backlights: list[BacklightInfo] = Field(default_factory=list)
|
|
168
|
+
framebuffers: list[str] = Field(default_factory=list) # /dev/fb* names
|
|
169
|
+
wlr_outputs: list[dict] = Field(default_factory=list) # raw wlr-randr output
|
|
170
|
+
|
|
171
|
+
# DSI specific
|
|
172
|
+
dsi_overlays: list[str] = Field(default_factory=list) # active dtoverlay lines
|
|
173
|
+
dsi_dmesg: list[str] = Field(default_factory=list) # relevant dmesg lines
|
|
174
|
+
|
|
175
|
+
# I2C
|
|
176
|
+
i2c_buses: list[I2CBusInfo] = Field(default_factory=list)
|
|
177
|
+
|
|
178
|
+
# GPIO header
|
|
179
|
+
gpio_4pin_detected: Optional[bool] = None # 5V/GND/SDA/SCL header present
|
|
180
|
+
|
|
181
|
+
# Diagnostics
|
|
182
|
+
diagnostics: list[HardwareDiagnostic] = Field(default_factory=list)
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def has_dsi(self) -> bool:
|
|
186
|
+
return any("DSI" in o.name for o in self.drm_outputs)
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def dsi_connected(self) -> bool:
|
|
190
|
+
return any("DSI" in o.name and o.status == "connected" for o in self.drm_outputs)
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
def dsi_enabled(self) -> bool:
|
|
194
|
+
return any("DSI" in o.name and o.enabled == "enabled" for o in self.drm_outputs)
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def backlight_on(self) -> bool:
|
|
198
|
+
return any(b.bl_power == 0 and b.brightness > 0 for b in self.backlights)
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def errors(self) -> list[HardwareDiagnostic]:
|
|
202
|
+
return [d for d in self.diagnostics if d.severity in ("error", "critical")]
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def warnings(self) -> list[HardwareDiagnostic]:
|
|
206
|
+
return [d for d in self.diagnostics if d.severity == "warning"]
|
|
207
|
+
|
|
208
|
+
|
|
123
209
|
class InfraState(BaseModel):
|
|
124
210
|
"""Full detected state of infrastructure — output of `detect`."""
|
|
125
211
|
host: str # "root@1.2.3.4" or "local"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.32
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -27,17 +27,17 @@ Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
|
27
27
|
|
|
28
28
|
## AI Cost Tracking
|
|
29
29
|
|
|
30
|
-
     
|
|
31
|
+
  
|
|
32
32
|
|
|
33
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
34
|
-
- 👤 **Human dev:** ~$
|
|
33
|
+
- 🤖 **LLM usage:** $7.5000 (52 commits)
|
|
34
|
+
- 👤 **Human dev:** ~$1755 (17.5h @ $100/h, 30min dedup)
|
|
35
35
|
|
|
36
36
|
Generated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
    
|
|
41
41
|
|
|
42
42
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
43
43
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|