clue2app-cli 0.3.0__tar.gz → 0.3.1__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 (37) hide show
  1. {clue2app_cli-0.3.0/src/clue2app_cli.egg-info → clue2app_cli-0.3.1}/PKG-INFO +1 -1
  2. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/pyproject.toml +1 -1
  3. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/main.py +110 -1
  4. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/sdk.py +18 -0
  5. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1/src/clue2app_cli.egg-info}/PKG-INFO +1 -1
  6. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/LICENSE +0 -0
  7. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/README.md +0 -0
  8. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/setup.cfg +0 -0
  9. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/__init__.py +0 -0
  10. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/agents/__init__.py +0 -0
  11. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/agents/ecr_healer.py +0 -0
  12. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/auth.py +0 -0
  13. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/config.py +0 -0
  14. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/core_client.py +0 -0
  15. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/creds_module.py +0 -0
  16. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/curses_wizard.py +0 -0
  17. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/directory_cmd.py +0 -0
  18. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/entrypoint_check.py +0 -0
  19. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/mcp_cmd.py +0 -0
  20. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tests_cmd.py +0 -0
  21. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tests_schema/__init__.py +0 -0
  22. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tests_schema/c2a-tests.v1.json +0 -0
  23. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tests_schema/validator.py +0 -0
  24. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui/__init__.py +0 -0
  25. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui/curses_app.py +0 -0
  26. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui/data.py +0 -0
  27. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui/screens/__init__.py +0 -0
  28. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui/textual_app.py +0 -0
  29. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui/widgets/__init__.py +0 -0
  30. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/tui_wizard.py +0 -0
  31. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/version.py +0 -0
  32. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli/wizard.py +0 -0
  33. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli.egg-info/SOURCES.txt +0 -0
  34. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli.egg-info/dependency_links.txt +0 -0
  35. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli.egg-info/entry_points.txt +0 -0
  36. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli.egg-info/requires.txt +0 -0
  37. {clue2app_cli-0.3.0 → clue2app_cli-0.3.1}/src/clue2app_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clue2app-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: CLI application for clue2app using the clue2app-python-sdk
5
5
  Author-email: Clue2App CLI Team <support@clue2app.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "clue2app-cli"
7
- version = "0.3.0"
7
+ version = "0.3.1"
8
8
  description = "CLI application for clue2app using the clue2app-python-sdk"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -3815,17 +3815,34 @@ def llm_create(name):
3815
3815
  """
3816
3816
  from .sdk import Clue2AppSDK
3817
3817
  from .auth import is_authenticated
3818
+ from .config import get_active_project
3818
3819
 
3819
3820
  if not is_authenticated():
3820
3821
  console.print("[red]Not authenticated.[/red] Run [bold]c2a login[/bold] first.")
3821
3822
  return
3822
3823
 
3824
+ # SCK-740 / clue2app-cli#117: coord's K8sServiceCatalogController.
3825
+ # resolveProjectId reads `projectId` (or `appGroupId`) from the request
3826
+ # body OR the query string. Previously this call sent only {"name": name},
3827
+ # so coord saw no project context and returned
3828
+ # 500 "No active project context for LLM Gateway instance creation"
3829
+ # even when `c2a project use <name>` had set the active project on this
3830
+ # machine. Every other project-scoped CLI verb reads get_active_project()
3831
+ # and threads the id through; llm_create was missed.
3832
+ active = get_active_project()
3833
+ if not active or not active.get("id"):
3834
+ console.print(
3835
+ "[red]No active project.[/red] Set one with "
3836
+ "[bold]c2a project use <name>[/bold] first."
3837
+ )
3838
+ return
3839
+
3823
3840
  sdk = Clue2AppSDK()
3824
3841
  try:
3825
3842
  resp = sdk._make_authenticated_request(
3826
3843
  "POST",
3827
3844
  "/api/k8s-service-catalog/llm-gateway",
3828
- json={"name": name},
3845
+ json={"name": name, "projectId": active.get("id")},
3829
3846
  )
3830
3847
  except Exception as e:
3831
3848
  console.print(f"[red]create call failed: {e}[/red]")
@@ -6553,6 +6570,98 @@ def project_show_cmd(ctx: ClueAppContext, name: str):
6553
6570
  console.print_exception()
6554
6571
 
6555
6572
 
6573
+ def _resolve_project(sdk, name_or_id):
6574
+ """SCK-737 shared helper: find a project by name, ns, or id. Returns dict or None."""
6575
+ for p in sdk.list_projects():
6576
+ if (p.get('name', '').lower() == name_or_id.lower()
6577
+ or p.get('ns', '').lower() == name_or_id.lower()
6578
+ or p.get('id') == name_or_id):
6579
+ return p
6580
+ return None
6581
+
6582
+
6583
+ @project_group.command(name='lock')
6584
+ @click.argument('name')
6585
+ @click.option('--yes', '-y', is_flag=True, help='Skip confirmation')
6586
+ @pass_context
6587
+ def project_lock_cmd(ctx: ClueAppContext, name: str, yes: bool):
6588
+ """Lock a project — blocks new app deploys until unlocked (SCK-737).
6589
+
6590
+ A locked project rejects `c2a app create` and new build triggers,
6591
+ but existing apps keep serving traffic. Caller must have
6592
+ PROJECT_ADMIN or SYSTEM.
6593
+
6594
+ Examples:
6595
+ c2a project lock my-project
6596
+ c2a project lock my-project --yes
6597
+ """
6598
+ from .sdk import Clue2AppSDK
6599
+ from .auth import is_authenticated
6600
+ from rich.prompt import Confirm
6601
+
6602
+ if not is_authenticated():
6603
+ console.print("[red]Not authenticated.[/red] Run [bold]c2a login[/bold] first.")
6604
+ return
6605
+
6606
+ try:
6607
+ sdk = Clue2AppSDK()
6608
+ found = _resolve_project(sdk, name)
6609
+ if not found:
6610
+ console.print(f"[red]Project not found:[/red] {name}")
6611
+ return
6612
+ if found.get('locked'):
6613
+ console.print(f"[yellow]Project '{found.get('name')}' is already locked.[/yellow]")
6614
+ return
6615
+ if not yes:
6616
+ if not Confirm.ask(
6617
+ f"Lock project '[bold]{found.get('name')}[/bold]'? "
6618
+ "New app deploys will be blocked until unlocked."):
6619
+ console.print("Cancelled.")
6620
+ return
6621
+ if sdk.set_project_locked(found['id'], True):
6622
+ console.print(f"[green]✓ Project '{found.get('name')}' locked.[/green]")
6623
+ console.print(f" Unlock with: [dim]c2a project unlock {found.get('name')}[/dim]")
6624
+ except Exception as e:
6625
+ console.print(f"[red]Error locking project:[/red] {e}")
6626
+ if ctx.debug:
6627
+ console.print_exception()
6628
+
6629
+
6630
+ @project_group.command(name='unlock')
6631
+ @click.argument('name')
6632
+ @pass_context
6633
+ def project_unlock_cmd(ctx: ClueAppContext, name: str):
6634
+ """Unlock a project — restores app-deploy capability (SCK-737).
6635
+
6636
+ Reverses `c2a project lock`. Caller must have PROJECT_ADMIN or SYSTEM.
6637
+
6638
+ Examples:
6639
+ c2a project unlock my-project
6640
+ """
6641
+ from .sdk import Clue2AppSDK
6642
+ from .auth import is_authenticated
6643
+
6644
+ if not is_authenticated():
6645
+ console.print("[red]Not authenticated.[/red] Run [bold]c2a login[/bold] first.")
6646
+ return
6647
+
6648
+ try:
6649
+ sdk = Clue2AppSDK()
6650
+ found = _resolve_project(sdk, name)
6651
+ if not found:
6652
+ console.print(f"[red]Project not found:[/red] {name}")
6653
+ return
6654
+ if not found.get('locked'):
6655
+ console.print(f"[yellow]Project '{found.get('name')}' is already unlocked.[/yellow]")
6656
+ return
6657
+ if sdk.set_project_locked(found['id'], False):
6658
+ console.print(f"[green]✓ Project '{found.get('name')}' unlocked.[/green]")
6659
+ except Exception as e:
6660
+ console.print(f"[red]Error unlocking project:[/red] {e}")
6661
+ if ctx.debug:
6662
+ console.print_exception()
6663
+
6664
+
6556
6665
  # === USER group ===
6557
6666
 
6558
6667
  @cli.group(name='user')
@@ -1288,6 +1288,24 @@ class Clue2AppSDK:
1288
1288
  console.print(f"[red]Error deleting project {project_id}:[/red] {e}")
1289
1289
  return False
1290
1290
 
1291
+ def set_project_locked(self, project_id: str, locked: bool) -> bool:
1292
+ """Lock or unlock a project (SCK-737).
1293
+
1294
+ Wraps coord's POST /api/k8s-project/{id}/locked/{true|false} —
1295
+ a locked project refuses new app deploys. Operator-level action;
1296
+ caller must have PROJECT_ADMIN or SYSTEM.
1297
+ """
1298
+ try:
1299
+ flag = "true" if locked else "false"
1300
+ response = self._make_authenticated_request(
1301
+ "POST", f"/api/k8s-project/{project_id}/locked/{flag}", timeout=30)
1302
+ response.raise_for_status()
1303
+ return True
1304
+ except requests.exceptions.RequestException as e:
1305
+ verb = "lock" if locked else "unlock"
1306
+ console.print(f"[red]Error {verb}ing project {project_id}:[/red] {e}")
1307
+ return False
1308
+
1291
1309
  def create_app(self, name: str, git_url: str, project_id: str = None,
1292
1310
  git_username: str = "git", git_password: str = "",
1293
1311
  branch: str = "main", config: Dict[str, Any] = None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clue2app-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: CLI application for clue2app using the clue2app-python-sdk
5
5
  Author-email: Clue2App CLI Team <support@clue2app.com>
6
6
  License: MIT
File without changes
File without changes
File without changes