ravmem-cli 1.1.1__tar.gz → 1.2.0__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.
Files changed (38) hide show
  1. {ravmem_cli-1.1.1/ravmem_cli.egg-info → ravmem_cli-1.2.0}/PKG-INFO +5 -3
  2. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/README.md +4 -2
  3. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/pyproject.toml +1 -1
  4. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/license.py +54 -7
  5. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0/ravmem_cli.egg-info}/PKG-INFO +5 -3
  6. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/LICENSE +0 -0
  7. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/__init__.py +0 -0
  8. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/_common.py +0 -0
  9. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/_errors.py +0 -0
  10. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/analyze.py +0 -0
  11. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/audit.py +0 -0
  12. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/auth.py +0 -0
  13. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/browse.py +0 -0
  14. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/config_cmd.py +0 -0
  15. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/diff.py +0 -0
  16. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/doctor.py +0 -0
  17. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/git_local.py +0 -0
  18. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/impact.py +0 -0
  19. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/info.py +0 -0
  20. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/kg.py +0 -0
  21. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/main.py +0 -0
  22. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/remote.py +0 -0
  23. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/search.py +0 -0
  24. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/cli/serve.py +0 -0
  25. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/client/__init__.py +0 -0
  26. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/client/api.py +0 -0
  27. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/client/config.py +0 -0
  28. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/config.py +0 -0
  29. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/config_loader.py +0 -0
  30. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/kg_config.py +0 -0
  31. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem/kg_init.py +0 -0
  32. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem_cli.egg-info/SOURCES.txt +0 -0
  33. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem_cli.egg-info/dependency_links.txt +0 -0
  34. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem_cli.egg-info/entry_points.txt +0 -0
  35. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem_cli.egg-info/requires.txt +0 -0
  36. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/ravmem_cli.egg-info/top_level.txt +0 -0
  37. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/setup.cfg +0 -0
  38. {ravmem_cli-1.1.1 → ravmem_cli-1.2.0}/tests/test_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ravmem-cli
3
- Version: 1.1.1
3
+ Version: 1.2.0
4
4
  Summary: RavMem CLI — lightweight client for the RavMem code knowledge graph server
5
5
  Author-email: RavMem <harpreet.singh@ravmem.com>
6
6
  License-Expression: MIT
@@ -44,8 +44,10 @@ pip install ravmem-cli
44
44
  # Point the CLI at your RavMem server
45
45
  ravmem remote config --url http://localhost:7432 --api-key <ADMIN_TOKEN>
46
46
 
47
- # Activate the license (one command: seals the key to this machine, then
48
- # brings the server live — the key is never stored in a file)
47
+ # Activate the license (one command: seals the key to the server's machine,
48
+ # then brings the server live — the key is saved on the server's own data
49
+ # volume so it survives restarts; it's never stored on the machine you run
50
+ # this CLI command from)
49
51
  ravmem license activate RAVMEM-XXXX-XXXX-XXXX-XXXX
50
52
 
51
53
  # Register a repository
@@ -14,8 +14,10 @@ pip install ravmem-cli
14
14
  # Point the CLI at your RavMem server
15
15
  ravmem remote config --url http://localhost:7432 --api-key <ADMIN_TOKEN>
16
16
 
17
- # Activate the license (one command: seals the key to this machine, then
18
- # brings the server live — the key is never stored in a file)
17
+ # Activate the license (one command: seals the key to the server's machine,
18
+ # then brings the server live — the key is saved on the server's own data
19
+ # volume so it survives restarts; it's never stored on the machine you run
20
+ # this CLI command from)
19
21
  ravmem license activate RAVMEM-XXXX-XXXX-XXXX-XXXX
20
22
 
21
23
  # Register a repository
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ravmem-cli"
7
- version = "1.1.1"
7
+ version = "1.2.0"
8
8
  description = "RavMem CLI — lightweight client for the RavMem code knowledge graph server"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -39,6 +39,24 @@ def _get_client():
39
39
  return RavMemClient(base_url=cfg["server_url"], api_key=cfg.get("api_key") or None)
40
40
 
41
41
 
42
+ def _post_with_key_fallback(client, con: Console, path: str, body: Optional[dict] = None) -> dict:
43
+ """POST to `path`; if the server has no license key on file, prompt for it
44
+ once and retry with it included in the body (the server persists it there,
45
+ so this shouldn't come up again on subsequent calls)."""
46
+ body = dict(body or {})
47
+ try:
48
+ return client.post(path, json=body)
49
+ except RavMemAPIError as exc:
50
+ if exc.status == 400 and "RAVMEM_LICENSE_KEY is not set" in (exc.detail or ""):
51
+ con.print("[yellow]Server has no license key on file — enter it to proceed.[/yellow]")
52
+ key = typer.prompt("License key", hide_input=True).strip()
53
+ if not key:
54
+ raise
55
+ body["license_key"] = key
56
+ return client.post(path, json=body)
57
+ raise
58
+
59
+
42
60
  # ---------------------------------------------------------------------------
43
61
  # ravmem license init
44
62
  # ---------------------------------------------------------------------------
@@ -106,9 +124,11 @@ def activate_cmd(
106
124
  ) -> None:
107
125
  """One-step activation: seal the license to this machine and bring the server live.
108
126
 
109
- The key is sent once, sealed to this machine (machine-bound), then discarded —
110
- it is never stored in .env. Works whether the server is in activation-only mode
111
- (first run) or already running.
127
+ The key is sent once and sealed to this machine (machine-bound). It's also
128
+ saved to the server's own data volume (not to its .env) so the license
129
+ survives restarts and container recreates without needing the key re-entered.
130
+ It is never stored on the machine you run this CLI command from. Works
131
+ whether the server is in activation-only mode (first run) or already running.
112
132
  """
113
133
  con = _console()
114
134
  if not key:
@@ -168,7 +188,34 @@ def activate_cmd(
168
188
  result = client.post("/api/license/init", json=init_payload)
169
189
  except RavMemAPIError as exc:
170
190
  if exc.status == 409:
171
- con.print("[bold green]License already initialized — ravmem is ready.[/bold green]")
191
+ # Already initialized — a 409 alone doesn't mean the stored token is
192
+ # still usable (e.g. a container recreate can make it undecryptable).
193
+ # Check token_integrity and repair if it isn't "ok" before declaring
194
+ # success.
195
+ con.print("[dim]License already initialized — verifying token integrity…[/dim]")
196
+ try:
197
+ status_data = client.get("/api/license/status")
198
+ except RavMemAPIError as exc2:
199
+ con.print(f"[red]Could not verify license status: {exc2}[/red]")
200
+ raise typer.Exit(1)
201
+
202
+ integrity = status_data.get("token_integrity")
203
+ if integrity == "ok":
204
+ con.print("[bold green]License already initialized — ravmem is ready.[/bold green]")
205
+ return
206
+
207
+ con.print(f"[yellow]Stored token integrity is '{integrity}' — repairing…[/yellow]")
208
+ try:
209
+ # Already have the key in scope from this activate call — no
210
+ # need to prompt again even if the server has nothing on file.
211
+ repair_result = client.post("/api/license/repair", json={"license_key": key})
212
+ except RavMemAPIError as exc3:
213
+ con.print(f"[red]Repair failed: {exc3}[/red]")
214
+ raise typer.Exit(1)
215
+
216
+ con.print("\n[bold green]License repaired. ravmem is ready.[/bold green]")
217
+ con.print(f" Status: {repair_result.get('status')}")
218
+ con.print(f" Expires: {repair_result.get('expiry_ts')}")
172
219
  return
173
220
  con.print(f"[red]Entitlement init failed: {exc}[/red]")
174
221
  raise typer.Exit(1)
@@ -374,7 +421,7 @@ def renew_cmd() -> None:
374
421
  client = _get_client()
375
422
  con.print("Renewing license…")
376
423
  try:
377
- result = client.post("/api/license/renew", json={})
424
+ result = _post_with_key_fallback(client, con, "/api/license/renew")
378
425
  except RavMemAPIError as exc:
379
426
  con.print(f"[red]Renewal failed: {exc}[/red]")
380
427
  raise typer.Exit(1)
@@ -397,7 +444,7 @@ def repair_cmd() -> None:
397
444
 
398
445
  client = _get_client()
399
446
  try:
400
- result = client.post("/api/license/repair", json={})
447
+ result = _post_with_key_fallback(client, con, "/api/license/repair")
401
448
  except RavMemAPIError as exc:
402
449
  con.print(f"[red]Repair failed: {exc}[/red]")
403
450
  raise typer.Exit(1)
@@ -463,7 +510,7 @@ def rebind_cmd() -> None:
463
510
 
464
511
  client = _get_client()
465
512
  try:
466
- result = client.post("/api/license/rebind", json={})
513
+ result = _post_with_key_fallback(client, con, "/api/license/rebind")
467
514
  except RavMemAPIError as exc:
468
515
  con.print(f"[red]Rebind request failed: {exc}[/red]")
469
516
  raise typer.Exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ravmem-cli
3
- Version: 1.1.1
3
+ Version: 1.2.0
4
4
  Summary: RavMem CLI — lightweight client for the RavMem code knowledge graph server
5
5
  Author-email: RavMem <harpreet.singh@ravmem.com>
6
6
  License-Expression: MIT
@@ -44,8 +44,10 @@ pip install ravmem-cli
44
44
  # Point the CLI at your RavMem server
45
45
  ravmem remote config --url http://localhost:7432 --api-key <ADMIN_TOKEN>
46
46
 
47
- # Activate the license (one command: seals the key to this machine, then
48
- # brings the server live — the key is never stored in a file)
47
+ # Activate the license (one command: seals the key to the server's machine,
48
+ # then brings the server live — the key is saved on the server's own data
49
+ # volume so it survives restarts; it's never stored on the machine you run
50
+ # this CLI command from)
49
51
  ravmem license activate RAVMEM-XXXX-XXXX-XXXX-XXXX
50
52
 
51
53
  # Register a repository
File without changes
File without changes
File without changes
File without changes
File without changes