luv-cli 0.0.16__tar.gz → 0.0.17__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.
- {luv_cli-0.0.16 → luv_cli-0.0.17}/PKG-INFO +4 -2
- {luv_cli-0.0.16 → luv_cli-0.0.17}/README.md +3 -1
- {luv_cli-0.0.16 → luv_cli-0.0.17}/luv/__init__.py +17 -4
- {luv_cli-0.0.16 → luv_cli-0.0.17}/pyproject.toml +1 -1
- {luv_cli-0.0.16 → luv_cli-0.0.17}/.claude/settings.json +0 -0
- {luv_cli-0.0.16 → luv_cli-0.0.17}/.failproofai/policies-config.json +0 -0
- {luv_cli-0.0.16 → luv_cli-0.0.17}/.github/workflows/publish.yml +0 -0
- {luv_cli-0.0.16 → luv_cli-0.0.17}/.gitignore +0 -0
- {luv_cli-0.0.16 → luv_cli-0.0.17}/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: luv-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.17
|
|
4
4
|
Summary: Launch Claude Code agents on GitHub repos with isolated workspaces and optional Docker dev environments
|
|
5
5
|
Project-URL: Homepage, https://github.com/exospherehost/luv
|
|
6
6
|
Project-URL: Repository, https://github.com/exospherehost/luv
|
|
@@ -87,6 +87,7 @@ All workspaces live under `~/prs/`. The number comes from the repo's GitHub issu
|
|
|
87
87
|
| `luv [org/]<repo> -pr <number> [prompt]` | Open a PR by repo + number |
|
|
88
88
|
| `luv --clean` | Delete workspaces where the branch is fully pushed/merged |
|
|
89
89
|
| `luv --clean -f` | Force delete all workspaces |
|
|
90
|
+
| `luv --clean --safe -f` | Force delete only workspaces older than 24h |
|
|
90
91
|
|
|
91
92
|
### Flags
|
|
92
93
|
|
|
@@ -98,6 +99,7 @@ All workspaces live under `~/prs/`. The number comes from the repo's GitHub issu
|
|
|
98
99
|
| `-nit` | Non-interactive: run `claude -p <prompt>` and exit (no REPL); streams `stream-json` events to stdout |
|
|
99
100
|
| `-e` | Env: pass `LUV_*` environment variables (with prefix stripped) into the session |
|
|
100
101
|
| `-f`, `--force` | Skip safety checks (with `--clean`) |
|
|
102
|
+
| `--safe` | With `--clean -f`, only delete workspaces older than 24h (mtime) |
|
|
101
103
|
|
|
102
104
|
## Docker dev environments
|
|
103
105
|
|
|
@@ -157,7 +159,7 @@ Docker mode works with all flags: `-n` opens a bash shell in the container, `-r`
|
|
|
157
159
|
- No unpushed commits
|
|
158
160
|
- If the remote branch is gone, verifies the PR was merged and local HEAD matches
|
|
159
161
|
|
|
160
|
-
Use `luv --clean -f` to skip all safety checks and delete everything.
|
|
162
|
+
Use `luv --clean -f` to skip all safety checks and delete everything. Add `--safe` (i.e. `luv --clean --safe -f`) to restrict force-delete to workspaces whose folder mtime is older than 24 hours, leaving recently-touched workspaces alone.
|
|
161
163
|
|
|
162
164
|
## Configuration
|
|
163
165
|
|
|
@@ -64,6 +64,7 @@ All workspaces live under `~/prs/`. The number comes from the repo's GitHub issu
|
|
|
64
64
|
| `luv [org/]<repo> -pr <number> [prompt]` | Open a PR by repo + number |
|
|
65
65
|
| `luv --clean` | Delete workspaces where the branch is fully pushed/merged |
|
|
66
66
|
| `luv --clean -f` | Force delete all workspaces |
|
|
67
|
+
| `luv --clean --safe -f` | Force delete only workspaces older than 24h |
|
|
67
68
|
|
|
68
69
|
### Flags
|
|
69
70
|
|
|
@@ -75,6 +76,7 @@ All workspaces live under `~/prs/`. The number comes from the repo's GitHub issu
|
|
|
75
76
|
| `-nit` | Non-interactive: run `claude -p <prompt>` and exit (no REPL); streams `stream-json` events to stdout |
|
|
76
77
|
| `-e` | Env: pass `LUV_*` environment variables (with prefix stripped) into the session |
|
|
77
78
|
| `-f`, `--force` | Skip safety checks (with `--clean`) |
|
|
79
|
+
| `--safe` | With `--clean -f`, only delete workspaces older than 24h (mtime) |
|
|
78
80
|
|
|
79
81
|
## Docker dev environments
|
|
80
82
|
|
|
@@ -134,7 +136,7 @@ Docker mode works with all flags: `-n` opens a bash shell in the container, `-r`
|
|
|
134
136
|
- No unpushed commits
|
|
135
137
|
- If the remote branch is gone, verifies the PR was merged and local HEAD matches
|
|
136
138
|
|
|
137
|
-
Use `luv --clean -f` to skip all safety checks and delete everything.
|
|
139
|
+
Use `luv --clean -f` to skip all safety checks and delete everything. Add `--safe` (i.e. `luv --clean --safe -f`) to restrict force-delete to workspaces whose folder mtime is older than 24 hours, leaving recently-touched workspaces alone.
|
|
138
140
|
|
|
139
141
|
## Configuration
|
|
140
142
|
|
|
@@ -6,6 +6,7 @@ import shutil
|
|
|
6
6
|
import subprocess
|
|
7
7
|
import sys
|
|
8
8
|
import tempfile
|
|
9
|
+
import time
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
11
12
|
LUV_DIR = Path.home() / ".luv"
|
|
@@ -391,7 +392,10 @@ def launch(clone_dir: Path, prompt: str | None, plan_mode: bool = False,
|
|
|
391
392
|
os.execv(claude_bin, [claude_bin] + common_flags + mode_flags + initial_args)
|
|
392
393
|
|
|
393
394
|
|
|
394
|
-
|
|
395
|
+
SAFE_AGE_SECONDS = 24 * 3600
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def cmd_clean(force: bool = False, safe: bool = False) -> None:
|
|
395
399
|
"""Scan ~/prs/ and delete fully-pushed, clean work folders."""
|
|
396
400
|
if not PRS_DIR.exists():
|
|
397
401
|
print("luv: nothing to clean (~/prs/ does not exist)")
|
|
@@ -399,6 +403,7 @@ def cmd_clean(force: bool = False) -> None:
|
|
|
399
403
|
|
|
400
404
|
cleaned: list[str] = []
|
|
401
405
|
skipped: list[tuple[str, str]] = []
|
|
406
|
+
now = time.time()
|
|
402
407
|
|
|
403
408
|
for entry in sorted(PRS_DIR.iterdir()):
|
|
404
409
|
if not entry.is_dir():
|
|
@@ -409,6 +414,9 @@ def cmd_clean(force: bool = False) -> None:
|
|
|
409
414
|
continue # doesn't match {repo}-{number} — skip silently
|
|
410
415
|
|
|
411
416
|
if force:
|
|
417
|
+
if safe and (now - entry.stat().st_mtime) < SAFE_AGE_SECONDS:
|
|
418
|
+
skipped.append((entry.name, "younger than 24h (--safe)"))
|
|
419
|
+
continue
|
|
412
420
|
shutil.rmtree(entry)
|
|
413
421
|
cleaned.append(entry.name)
|
|
414
422
|
continue
|
|
@@ -589,8 +597,9 @@ def main() -> None:
|
|
|
589
597
|
plan_mode = "-p" in args
|
|
590
598
|
non_interactive = "-nit" in args
|
|
591
599
|
force = "-f" in args or "--force" in args
|
|
600
|
+
safe = "--safe" in args
|
|
592
601
|
env_mode = "-e" in args
|
|
593
|
-
args = [a for a in args if a not in ("-n", "-r", "-e", "-f", "--force", "-p", "-nit")]
|
|
602
|
+
args = [a for a in args if a not in ("-n", "-r", "-e", "-f", "--force", "-p", "-nit", "--safe")]
|
|
594
603
|
extra_env = collect_luv_env() if env_mode else {}
|
|
595
604
|
|
|
596
605
|
if not args or args[0] in ("-h", "--help"):
|
|
@@ -604,6 +613,7 @@ Flags:
|
|
|
604
613
|
-nit non-interactive: run claude -p <prompt> and exit (no REPL)
|
|
605
614
|
-e env: pass LUV_* environment variables (with prefix stripped) into the session
|
|
606
615
|
-f, --force (with --clean) skip safety checks and delete all work folders
|
|
616
|
+
--safe (with --clean -f) only delete folders older than 24h
|
|
607
617
|
|
|
608
618
|
Commands:
|
|
609
619
|
luv --init configure default GitHub org
|
|
@@ -613,7 +623,7 @@ Commands:
|
|
|
613
623
|
luv [org/]<repo> -pr <number> [prompt] open a GitHub PR by repo + number
|
|
614
624
|
luv [org/]<repo> -n open shell in latest local clone
|
|
615
625
|
luv [org/]<repo> -r resume Claude in latest local clone
|
|
616
|
-
luv --clean [-f]
|
|
626
|
+
luv --clean [-f] [--safe] delete fully-pushed work folders
|
|
617
627
|
|
|
618
628
|
Org resolution:
|
|
619
629
|
Explicit org/repo overrides the default. Run 'luv --init' to set a default.
|
|
@@ -625,8 +635,11 @@ Docker:
|
|
|
625
635
|
"dev-environment" service. Torn down automatically on exit.""")
|
|
626
636
|
sys.exit(0)
|
|
627
637
|
|
|
638
|
+
if safe and (args[0] != "--clean" or not force):
|
|
639
|
+
die("--safe only works with --clean -f")
|
|
640
|
+
|
|
628
641
|
if args[0] == "--clean":
|
|
629
|
-
cmd_clean(force=force)
|
|
642
|
+
cmd_clean(force=force, safe=safe)
|
|
630
643
|
return
|
|
631
644
|
|
|
632
645
|
if args[0] == "--init":
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "luv-cli"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.17"
|
|
8
8
|
description = "Launch Claude Code agents on GitHub repos with isolated workspaces and optional Docker dev environments"
|
|
9
9
|
requires-python = ">=3.10"
|
|
10
10
|
license = "MIT"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|