devin-cli 1.1.1__tar.gz → 1.1.3__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 (55) hide show
  1. {devin_cli-1.1.1 → devin_cli-1.1.3}/CHANGELOG.md +12 -0
  2. {devin_cli-1.1.1 → devin_cli-1.1.3}/PKG-INFO +1 -1
  3. {devin_cli-1.1.1 → devin_cli-1.1.3}/pyproject.toml +1 -1
  4. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/cli.py +39 -11
  5. devin_cli-1.1.3/test_profile.py +3 -0
  6. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_cli.py +1 -1
  7. {devin_cli-1.1.1 → devin_cli-1.1.3}/.github/workflows/pypi-publish.yml +0 -0
  8. {devin_cli-1.1.1 → devin_cli-1.1.3}/.gitignore +0 -0
  9. {devin_cli-1.1.1 → devin_cli-1.1.3}/LICENSE +0 -0
  10. {devin_cli-1.1.1 → devin_cli-1.1.3}/README.md +0 -0
  11. {devin_cli-1.1.1 → devin_cli-1.1.3}/assets/logo.png +0 -0
  12. {devin_cli-1.1.1 → devin_cli-1.1.3}/generate_facades.py +0 -0
  13. {devin_cli-1.1.1 → devin_cli-1.1.3}/setup.py +0 -0
  14. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/__init__.py +0 -0
  15. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/__init__.py +0 -0
  16. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/attachments.py +0 -0
  17. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/client.py +0 -0
  18. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/consumption.py +0 -0
  19. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/knowledge.py +0 -0
  20. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/members.py +0 -0
  21. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/organizations.py +0 -0
  22. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/playbooks.py +0 -0
  23. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/repositories.py +0 -0
  24. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/schedules.py +0 -0
  25. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/secrets.py +0 -0
  26. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/sessions.py +0 -0
  27. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v1/__init__.py +0 -0
  28. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v1/attachments.py +0 -0
  29. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v1/knowledge.py +0 -0
  30. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v1/playbooks.py +0 -0
  31. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v1/secrets.py +0 -0
  32. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v1/sessions.py +0 -0
  33. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/__init__.py +0 -0
  34. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/attachments.py +0 -0
  35. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/consumption.py +0 -0
  36. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/knowledge.py +0 -0
  37. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/members.py +0 -0
  38. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/organizations.py +0 -0
  39. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/playbooks.py +0 -0
  40. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/repositories.py +0 -0
  41. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/schedules.py +0 -0
  42. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/secrets.py +0 -0
  43. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/api/v3/sessions.py +0 -0
  44. {devin_cli-1.1.1 → devin_cli-1.1.3}/src/devin_cli/config.py +0 -0
  45. {devin_cli-1.1.1 → devin_cli-1.1.3}/test_duplicate.py +0 -0
  46. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/__init__.py +0 -0
  47. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/conftest.py +0 -0
  48. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_attachments.py +0 -0
  49. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_knowledge.py +0 -0
  50. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_playbooks.py +0 -0
  51. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_repositories.py +0 -0
  52. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_schedules.py +0 -0
  53. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_secrets.py +0 -0
  54. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_api/test_sessions.py +0 -0
  55. {devin_cli-1.1.1 → devin_cli-1.1.3}/tests/test_config.py +0 -0
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.3] - 2026-03-11
9
+ ### Fixed
10
+ - `repos list` now resolves blank Path column by trying `repository_path`, `path`, and `name` keys from the API response.
11
+ - `secrets list` no longer crashes when the API returns a raw list instead of a dict with a key.
12
+ - `sessions cost <id>` now pulls cost data from the org-scoped `get_session` endpoint instead of the enterprise-only consumption path.
13
+ - `sessions insights` on v1 now displays a readable error with a hint to switch to v3 instead of a confusing JSON blob.
14
+ - `--json` flag added to `repos list` and `secrets list` for raw programmatic output.
15
+
16
+ ## [1.1.2] - 2026-03-11
17
+ ### Fixed
18
+ - **Critical Profile Bug**: Stopped `cli.py` from statically overriding the active user profile back to `"default"` on every boot unless the `--profile` flag is explicitly passed over the terminal.
19
+
8
20
  ## [1.1.1] - 2026-03-11
9
21
  ### Fixed
10
22
  - Fixed v1 API HTTP redirects stripping authorization headers on org-scoped endpoints (403 errors).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devin-cli
3
- Version: 1.1.1
3
+ Version: 1.1.3
4
4
  Summary: Unofficial CLI for Devin AI - The first AI Software Engineer
5
5
  Project-URL: Homepage, https://github.com/revanthpobala/devin-cli
6
6
  Project-URL: Repository, https://github.com/revanthpobala/devin-cli.git
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devin-cli"
3
- version = "1.1.1"
3
+ version = "1.1.3"
4
4
  description = "Unofficial CLI for Devin AI - The first AI Software Engineer"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -78,7 +78,7 @@ ASCII_LOGO = r"""
78
78
  @app.callback(invoke_without_command=True)
79
79
  def main(
80
80
  ctx: typer.Context,
81
- profile: str = typer.Option("default", "--profile", "-p", help="Configuration profile to use (e.g., service, personal)"),
81
+ profile: Optional[str] = typer.Option(None, "--profile", "-p", help="Configuration profile to use (e.g., service, personal)"),
82
82
  version: Optional[bool] = typer.Option(None, "--version", "-v", help="Show the application's version and exit."),
83
83
  ):
84
84
  """
@@ -88,7 +88,8 @@ def main(
88
88
  console.print(f"devin CLI version: {__version__}")
89
89
  raise typer.Exit()
90
90
 
91
- config.active_profile = profile
91
+ if profile:
92
+ config.active_profile = profile
92
93
  if ctx.invoked_subcommand is None:
93
94
  console.print(ASCII_LOGO)
94
95
 
@@ -254,7 +255,11 @@ def session_insights_cmd(
254
255
  if org: config.temporary_org_id = org
255
256
  sid = session_id or get_current_session_id()
256
257
  resp = sessions.get_session_insights(sid)
257
- console.print(Panel(json.dumps(resp, indent=2), title=f"Insights for {sid}"))
258
+ if isinstance(resp, dict) and "error" in resp:
259
+ console.print(f"[bold yellow]Note:[/bold yellow] {resp['error']}")
260
+ console.print("Tip: Switch to v3 with [bold cyan]devin configure[/bold cyan] or use [bold cyan]--profile [v3-profile][/bold cyan]")
261
+ else:
262
+ console.print(Panel(json.dumps(resp, indent=2), title=f"Insights for {sid}"))
258
263
 
259
264
  @session_app.command("cost")
260
265
  @handle_api_error
@@ -265,10 +270,12 @@ def session_cost_cmd(
265
270
  """View ACU consumption."""
266
271
  if org: config.temporary_org_id = org
267
272
  if session_id:
268
- resp = consumption.get_session_consumption(session_id)
273
+ resp = sessions.get_session(session_id)
274
+ cost_data = {"session_id": resp.get("session_id"), "status": resp.get("status_enum"), "acu_used": resp.get("acu_used")}
275
+ console.print(Panel(json.dumps(cost_data, indent=2), title=f"Session Cost: {session_id}"))
269
276
  else:
270
277
  resp = consumption.get_daily_consumption_breakdown()
271
- console.print(Panel(json.dumps(resp, indent=2), title="Consumption Data"))
278
+ console.print(Panel(json.dumps(resp, indent=2), title="Daily Consumption"))
272
279
 
273
280
  @session_app.command("message")
274
281
  @handle_api_error
@@ -424,15 +431,29 @@ def delete_playbook_cmd(
424
431
  # --- Secrets ---
425
432
  @secret_app.command("list")
426
433
  @handle_api_error
427
- def list_secrets_cmd(org: Optional[str] = typer.Option(None, "--org")):
434
+ def list_secrets_cmd(
435
+ org: Optional[str] = typer.Option(None, "--org"),
436
+ json_output: bool = typer.Option(False, "--json"),
437
+ ):
428
438
  """List organization secrets."""
429
439
  if org: config.temporary_org_id = org
430
440
  resp = secrets.list_secrets()
441
+ if isinstance(resp, dict):
442
+ items = resp.get("secrets", resp.get("items", []))
443
+ elif isinstance(resp, list):
444
+ items = resp
445
+ else:
446
+ console.print(f"[yellow]Unexpected response format: {type(resp).__name__}[/yellow]")
447
+ items = []
448
+ if json_output:
449
+ console.print(json.dumps(items, indent=2))
450
+ return
431
451
  table = Table(title="Secrets")
432
452
  table.add_column("ID", style="cyan")
433
453
  table.add_column("Name")
434
- for item in resp:
435
- table.add_row(item.get("id"), item.get("name"))
454
+ for item in items:
455
+ if isinstance(item, dict):
456
+ table.add_row(item.get("id"), item.get("name"))
436
457
  console.print(table)
437
458
 
438
459
  @secret_app.command("delete")
@@ -491,16 +512,23 @@ def create_schedule_cmd(
491
512
  # --- Repositories ---
492
513
  @repo_app.command("list")
493
514
  @handle_api_error
494
- def list_repos_cmd(org: Optional[str] = typer.Option(None, "--org")):
515
+ def list_repos_cmd(
516
+ org: Optional[str] = typer.Option(None, "--org"),
517
+ json_output: bool = typer.Option(False, "--json"),
518
+ ):
495
519
  """List repositories indexed for Devin."""
496
520
  if org: config.temporary_org_id = org
497
521
  resp = repositories.list_repositories()
498
- items = resp.get("items", [])
522
+ items = resp.get("repositories", resp.get("items", []))
523
+ if json_output:
524
+ console.print(json.dumps(items, indent=2))
525
+ return
499
526
  table = Table(title="Repositories")
500
527
  table.add_column("Path", style="cyan")
501
528
  table.add_column("Indexed", style="green")
502
529
  for item in items:
503
- table.add_row(item.get("repository_path"), "Yes" if item.get("is_indexed") else "No")
530
+ path = item.get("repository_path") or item.get("path") or item.get("name", "")
531
+ table.add_row(path, "Yes" if item.get("is_indexed") else "No")
504
532
  console.print(table)
505
533
 
506
534
  @repo_app.command("index")
@@ -0,0 +1,3 @@
1
+ from devin_cli.config import config
2
+ config.active_profile = "test_v1"
3
+ config.api_version = "v1"
@@ -7,7 +7,7 @@ runner = CliRunner()
7
7
  def test_app_help():
8
8
  result = runner.invoke(app, ["--help"])
9
9
  assert result.exit_code == 0
10
- assert "Unofficial CLI for Devin AI v3" in result.stdout
10
+ assert "Unofficial CLI for Devin AI" in result.stdout
11
11
 
12
12
  def test_app_configure_help():
13
13
  result = runner.invoke(app, ["configure", "--help"])
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