redeploy 0.2.26__tar.gz → 0.2.27__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.26 → redeploy-0.2.27}/PKG-INFO +6 -6
- {redeploy-0.2.26 → redeploy-0.2.27}/README.md +5 -5
- {redeploy-0.2.26 → redeploy-0.2.27}/pyproject.toml +1 -1
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/__init__.py +1 -1
- redeploy-0.2.27/redeploy/apply/exceptions.py +12 -0
- redeploy-0.2.27/redeploy/apply/progress.py +106 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy.egg-info/PKG-INFO +6 -6
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy.egg-info/SOURCES.txt +2 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/apply/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/apply/executor.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/apply/state.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/audit.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/audit.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/detect.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/devices.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/diagnose.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/diff.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/exec_.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/export.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/import_.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/init.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/inspect.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/patterns.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/plan_apply.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/plugin.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/probe.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/state.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/status.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/target.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/version.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/commands/workflow.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/core.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli/display.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/cli.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/data_sync.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/detect/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/detect/detector.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/detect/probes.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/detect/remote.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/detect/templates.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/detect/workflow.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/discovery.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl/loader.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl/parser.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/context.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/decorators.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/docker_steps.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/exceptions.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/runner.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/dsl_python/steps.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/fleet.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/iac/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/iac/base.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/iac/docker_compose.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/iac/parsers/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/iac/parsers/compose.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/iac/registry.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/markpact/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/markpact/compiler.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/markpact/models.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/markpact/parser.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/models.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/observe.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/parse.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/patterns.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plan/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plan/planner.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plugins/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plugins/builtin/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plugins/builtin/browser_reload.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plugins/builtin/notify.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/plugins/builtin/systemd_reload.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/spec_loader.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/ssh.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/steps.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_audit.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_cli.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_data_sync.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_discovery.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_dsl.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_examples.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_executor.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_fleet.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_git_integration.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_iac.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_manifest.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_markpact_compiler.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_markpact_parser.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_models.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_observe.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_parse.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_patterns.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_planner_edge.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_plugins.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_probes.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_public_api.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_resume.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_spec_loader.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_ssh.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_templates.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_verify.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_version.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_version_changelog.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_version_cli.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_version_manifest.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_version_sources.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/tests/test_workflow.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/verify.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/bump.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/changelog.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/commits.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/diff.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/git_integration.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/git_transaction.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/manifest.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/__init__.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/base.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/json_.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/plain.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/regex.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/toml_.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/sources/yaml_.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version/transaction.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy/version.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy.egg-info/dependency_links.txt +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy.egg-info/entry_points.txt +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy.egg-info/requires.txt +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/redeploy.egg-info/top_level.txt +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/setup.cfg +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/tests/test_iac.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/tests/test_parse.py +0 -0
- {redeploy-0.2.26 → redeploy-0.2.27}/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.27
|
|
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:** $
|
|
34
|
-
- 👤 **Human dev:** ~$
|
|
33
|
+
- 🤖 **LLM usage:** $7.0500 (47 commits)
|
|
34
|
+
- 👤 **Human dev:** ~$1435 (14.3h @ $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:** $
|
|
10
|
-
- 👤 **Human dev:** ~$
|
|
9
|
+
- 🤖 **LLM usage:** $7.0500 (47 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$1435 (14.3h @ $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.27"
|
|
11
11
|
|
|
12
12
|
# ── Core models ───────────────────────────────────────────────────────────────
|
|
13
13
|
from .models import ( # noqa: F401
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Exceptions for the apply package."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from ..models import MigrationStep
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StepError(Exception):
|
|
8
|
+
"""Exception raised when a migration step fails."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, step: MigrationStep, msg: str):
|
|
11
|
+
self.step = step
|
|
12
|
+
super().__init__(f"[{step.id}] {msg}")
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Progress emission for migration execution."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
from typing import IO, Optional
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
from loguru import logger
|
|
10
|
+
|
|
11
|
+
from ..models import MigrationPlan, MigrationStep
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ProgressEmitter:
|
|
15
|
+
"""Emits YAML-formatted progress events to a stream (default: stdout).
|
|
16
|
+
|
|
17
|
+
Each event is a YAML document (separated by ---) so consumers can
|
|
18
|
+
parse the stream incrementally with yaml.safe_load_all().
|
|
19
|
+
|
|
20
|
+
Event types:
|
|
21
|
+
- start : deployment begins
|
|
22
|
+
- step_start: a single step begins
|
|
23
|
+
- step_done : step completed successfully
|
|
24
|
+
- step_fail : step failed with error
|
|
25
|
+
- progress : mid-step progress update (build cache, container status…)
|
|
26
|
+
- done : all steps completed
|
|
27
|
+
- failed : deployment failed
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, stream: IO[str] = None):
|
|
31
|
+
self._out = stream or sys.stdout
|
|
32
|
+
self._t0 = time.monotonic()
|
|
33
|
+
|
|
34
|
+
def _ts(self) -> str:
|
|
35
|
+
return datetime.now(timezone.utc).strftime("%H:%M:%S")
|
|
36
|
+
|
|
37
|
+
def _elapsed(self) -> float:
|
|
38
|
+
return round(time.monotonic() - self._t0, 1)
|
|
39
|
+
|
|
40
|
+
def _emit(self, event: dict) -> None:
|
|
41
|
+
event.setdefault("ts", self._ts())
|
|
42
|
+
event.setdefault("elapsed_s", self._elapsed())
|
|
43
|
+
self._out.write("---\n")
|
|
44
|
+
self._out.write(yaml.dump(event, default_flow_style=False, allow_unicode=True))
|
|
45
|
+
self._out.flush()
|
|
46
|
+
|
|
47
|
+
def start(self, plan: MigrationPlan) -> None:
|
|
48
|
+
from ..models import StepStatus
|
|
49
|
+
|
|
50
|
+
self._emit({
|
|
51
|
+
"event": "start",
|
|
52
|
+
"host": plan.host,
|
|
53
|
+
"strategy": f"{plan.from_strategy.value} → {plan.to_strategy.value}",
|
|
54
|
+
"total_steps": len(plan.steps),
|
|
55
|
+
"steps": [
|
|
56
|
+
{"n": i + 1, "id": s.id, "action": s.action.value,
|
|
57
|
+
"description": s.description, "status": s.status.value}
|
|
58
|
+
for i, s in enumerate(plan.steps)
|
|
59
|
+
],
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
def step_start(self, n: int, step: MigrationStep) -> None:
|
|
63
|
+
self._emit({
|
|
64
|
+
"event": "step_start",
|
|
65
|
+
"n": n,
|
|
66
|
+
"id": step.id,
|
|
67
|
+
"action": step.action.value,
|
|
68
|
+
"description": step.description,
|
|
69
|
+
"status": "running",
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
def step_done(self, n: int, step: MigrationStep) -> None:
|
|
73
|
+
self._emit({
|
|
74
|
+
"event": "step_done",
|
|
75
|
+
"n": n,
|
|
76
|
+
"id": step.id,
|
|
77
|
+
"status": "done",
|
|
78
|
+
"result": step.result,
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
def step_fail(self, n: int, step: MigrationStep, error: str) -> None:
|
|
82
|
+
self._emit({
|
|
83
|
+
"event": "step_fail",
|
|
84
|
+
"n": n,
|
|
85
|
+
"id": step.id,
|
|
86
|
+
"status": "failed",
|
|
87
|
+
"error": error,
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
def progress(self, step_id: str, message: str) -> None:
|
|
91
|
+
self._emit({
|
|
92
|
+
"event": "progress",
|
|
93
|
+
"id": step_id,
|
|
94
|
+
"message": message,
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
def done(self, total: int) -> None:
|
|
98
|
+
self._emit({"event": "done", "steps_completed": total, "result": "ok"})
|
|
99
|
+
|
|
100
|
+
def failed(self, completed: int, total: int, error: str) -> None:
|
|
101
|
+
self._emit({
|
|
102
|
+
"event": "failed",
|
|
103
|
+
"steps_completed": completed,
|
|
104
|
+
"steps_total": total,
|
|
105
|
+
"error": error,
|
|
106
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.27
|
|
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:** $
|
|
34
|
-
- 👤 **Human dev:** ~$
|
|
33
|
+
- 🤖 **LLM usage:** $7.0500 (47 commits)
|
|
34
|
+
- 👤 **Human dev:** ~$1435 (14.3h @ $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
|
|
|
@@ -22,7 +22,9 @@ redeploy.egg-info/entry_points.txt
|
|
|
22
22
|
redeploy.egg-info/requires.txt
|
|
23
23
|
redeploy.egg-info/top_level.txt
|
|
24
24
|
redeploy/apply/__init__.py
|
|
25
|
+
redeploy/apply/exceptions.py
|
|
25
26
|
redeploy/apply/executor.py
|
|
27
|
+
redeploy/apply/progress.py
|
|
26
28
|
redeploy/apply/state.py
|
|
27
29
|
redeploy/cli/__init__.py
|
|
28
30
|
redeploy/cli/core.py
|
|
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
|