arga-cli 0.1.7__tar.gz → 0.1.8__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.
- {arga_cli-0.1.7 → arga_cli-0.1.8}/PKG-INFO +1 -1
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/main.py +18 -3
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/__init__.py +13 -1
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/provision.py +10 -1
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli.egg-info/PKG-INFO +1 -1
- {arga_cli-0.1.7 → arga_cli-0.1.8}/pyproject.toml +1 -1
- {arga_cli-0.1.7 → arga_cli-0.1.8}/README.md +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/__init__.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/mcp.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/constants.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/env.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/output.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/prompts.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/session.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli/wizard/summary.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli.egg-info/SOURCES.txt +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli.egg-info/dependency_links.txt +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli.egg-info/entry_points.txt +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli.egg-info/requires.txt +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/arga_cli.egg-info/top_level.txt +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/setup.cfg +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/tests/test_cli_git.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/tests/test_cli_mcp.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/tests/test_cli_runs.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/tests/test_cli_test_url.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/tests/test_cli_validate_config.py +0 -0
- {arga_cli-0.1.7 → arga_cli-0.1.8}/tests/test_cli_validate_pr.py +0 -0
|
@@ -275,7 +275,8 @@ class ApiClient:
|
|
|
275
275
|
if response.status_code == 401:
|
|
276
276
|
raise NotAuthenticatedError("Error: Not authenticated. Run `arga login`.")
|
|
277
277
|
if response.status_code == 403:
|
|
278
|
-
|
|
278
|
+
if not detail:
|
|
279
|
+
message += " Your plan may not support this feature. Check with `arga whoami`."
|
|
279
280
|
elif response.status_code == 404:
|
|
280
281
|
message += " Check that your plan supports this feature with `arga whoami`."
|
|
281
282
|
elif response.status_code == 429:
|
|
@@ -482,11 +483,16 @@ def _print_twin_env_vars(status: dict) -> None:
|
|
|
482
483
|
from arga_cli.wizard.provision import with_proxy_token
|
|
483
484
|
|
|
484
485
|
proxy_token = status.get("proxy_token")
|
|
486
|
+
# Public `pub-` hosts don't do proxy auth, so the base_url is directly
|
|
487
|
+
# callable from any native SDK (Slack, Stripe, Discord, …). Appending
|
|
488
|
+
# `?token=…` would be harmless but misleading — it'd suggest the token
|
|
489
|
+
# is required, which is exactly the friction public twins eliminate.
|
|
490
|
+
is_public = bool(status.get("is_public"))
|
|
485
491
|
print("\nTwin environment variables — update your app's config to point at these:\n")
|
|
486
492
|
for name, info in status.get("twins", {}).items():
|
|
487
493
|
label = info.get("label", name)
|
|
488
494
|
base_url = info.get("base_url", "")
|
|
489
|
-
if proxy_token and base_url:
|
|
495
|
+
if not is_public and proxy_token and base_url:
|
|
490
496
|
base_url = with_proxy_token(base_url, proxy_token)
|
|
491
497
|
print(f" {label}:")
|
|
492
498
|
print(f" Base URL: {base_url}")
|
|
@@ -1337,6 +1343,7 @@ def _wizard_help_text() -> str:
|
|
|
1337
1343
|
" env Re-run .env rewriting step\n\n"
|
|
1338
1344
|
"Options:\n"
|
|
1339
1345
|
" --api-url API base URL\n"
|
|
1346
|
+
" --ttl MINUTES Session TTL in minutes (paid/team: 1-480, default 60; free: fixed 10)\n"
|
|
1340
1347
|
" --no-shape-detect Disable heuristic detection of API keys by value pattern\n"
|
|
1341
1348
|
" -h, --help Show this help"
|
|
1342
1349
|
)
|
|
@@ -1345,6 +1352,7 @@ def _wizard_help_text() -> str:
|
|
|
1345
1352
|
def _build_wizard_init_parser() -> argparse.ArgumentParser:
|
|
1346
1353
|
parser = argparse.ArgumentParser(prog="arga wizard", allow_abbrev=False)
|
|
1347
1354
|
parser.add_argument("--api-url", default=DEFAULT_API_URL, help="Arga API base URL")
|
|
1355
|
+
parser.add_argument("--ttl", type=int, default=None, help="Session TTL in minutes (paid/team: 1-480, default 60)")
|
|
1348
1356
|
parser.add_argument("--no-shape-detect", action="store_true", default=False)
|
|
1349
1357
|
return parser
|
|
1350
1358
|
|
|
@@ -1369,6 +1377,7 @@ def run_wizard_init(args: argparse.Namespace) -> int:
|
|
|
1369
1377
|
api_key=api_key,
|
|
1370
1378
|
cwd=os.getcwd(),
|
|
1371
1379
|
shape_detect=not getattr(args, "no_shape_detect", False),
|
|
1380
|
+
ttl_minutes=args.ttl,
|
|
1372
1381
|
)
|
|
1373
1382
|
|
|
1374
1383
|
|
|
@@ -1396,9 +1405,15 @@ def run_wizard_status(_args: argparse.Namespace) -> int:
|
|
|
1396
1405
|
f"Status: {'[green]' + status['status'] + '[/green]' if status['status'] == 'ready' else '[yellow]' + status['status'] + '[/yellow]'}",
|
|
1397
1406
|
"",
|
|
1398
1407
|
]
|
|
1408
|
+
# Public `pub-` hosts are drop-in callable without the proxy token; only
|
|
1409
|
+
# decorate private hosts so the printed URL accurately reflects what
|
|
1410
|
+
# the user needs to use.
|
|
1411
|
+
is_public = bool(status.get("is_public"))
|
|
1412
|
+
proxy_token = status.get("proxy_token")
|
|
1399
1413
|
for name, info in status.get("twins", {}).items():
|
|
1400
1414
|
label = TWIN_CATALOG.get(name, {}).get("label", name).ljust(16)
|
|
1401
|
-
|
|
1415
|
+
base_url = info.get("base_url", "")
|
|
1416
|
+
url = base_url if is_public else with_proxy_token(base_url, proxy_token)
|
|
1402
1417
|
lines.append(f"{label} [underline]{url}[/underline]")
|
|
1403
1418
|
if status.get("expires_at"):
|
|
1404
1419
|
lines.append("")
|
|
@@ -15,6 +15,7 @@ def run_wizard(
|
|
|
15
15
|
api_key: str | None = None,
|
|
16
16
|
cwd: str,
|
|
17
17
|
shape_detect: bool = True,
|
|
18
|
+
ttl_minutes: int | None = None,
|
|
18
19
|
) -> int:
|
|
19
20
|
"""Run the full quickstart wizard."""
|
|
20
21
|
from arga_cli.main import ApiClient
|
|
@@ -57,9 +58,20 @@ def run_wizard(
|
|
|
57
58
|
env_changes = rewrite_env_files(cwd, selected, shape_detect=shape_detect)
|
|
58
59
|
|
|
59
60
|
# Step 5: Provision
|
|
61
|
+
if ttl_minutes is not None:
|
|
62
|
+
resolved_ttl = ttl_minutes
|
|
63
|
+
elif billing_plan == "free":
|
|
64
|
+
resolved_ttl = 10
|
|
65
|
+
else:
|
|
66
|
+
resolved_ttl = 60
|
|
60
67
|
try:
|
|
61
|
-
status = provision_twins(client, selected, ttl_minutes=
|
|
68
|
+
status = provision_twins(client, selected, ttl_minutes=resolved_ttl, scenario_prompt=scenario_prompt)
|
|
62
69
|
except Exception as exc:
|
|
70
|
+
msg = str(exc)
|
|
71
|
+
if "provisions remaining" in msg.lower():
|
|
72
|
+
error("\n You've used all 5 quickstart provisions.")
|
|
73
|
+
yellow(" Run `arga login` to authenticate with your full account for unlimited access.\n")
|
|
74
|
+
return 1
|
|
63
75
|
error(f"\n Provisioning failed: {exc}")
|
|
64
76
|
if env_changes:
|
|
65
77
|
yellow(" Your .env has been updated. You can re-run the wizard to retry provisioning.")
|
|
@@ -114,7 +114,7 @@ def _format_seed_summary(seed_info: dict) -> list[str]:
|
|
|
114
114
|
counts = [
|
|
115
115
|
f"{key.replace('_', ' ')}: {value}"
|
|
116
116
|
for key, value in seed_info.items()
|
|
117
|
-
if key not in {"status", "twin"} and isinstance(value, (int, str))
|
|
117
|
+
if key not in {"status", "twin", "guild_id", "channel_ids"} and isinstance(value, (int, str))
|
|
118
118
|
]
|
|
119
119
|
return [f"Seeded — {', '.join(counts)}"] if counts else ["Seeded."]
|
|
120
120
|
if status_value == "skipped":
|
|
@@ -167,6 +167,15 @@ def seed_and_report(client: Any, status: dict) -> None:
|
|
|
167
167
|
env_vars = info.get("env_vars", {})
|
|
168
168
|
for key, val in env_vars.items():
|
|
169
169
|
console.print(f" [dim]{key}[/dim]: {val}")
|
|
170
|
+
|
|
171
|
+
# Print IDs from seed results (guild_id, channel_ids, etc.)
|
|
172
|
+
if seed_info is not None:
|
|
173
|
+
if seed_info.get("guild_id"):
|
|
174
|
+
console.print(f" [dim]GUILD_ID[/dim]: {seed_info['guild_id']}")
|
|
175
|
+
channel_ids = seed_info.get("channel_ids")
|
|
176
|
+
if channel_ids:
|
|
177
|
+
console.print(f" [dim]CHANNEL_IDS[/dim]: {', '.join(channel_ids)}")
|
|
178
|
+
|
|
170
179
|
console.print()
|
|
171
180
|
|
|
172
181
|
# Report backend-only twins
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "arga-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.8"
|
|
8
8
|
description = "Command-line interface for Arga authentication, MCP installation, and browser validation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
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
|