devin-cli 1.1.9__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 (53) hide show
  1. {devin_cli-1.1.9 → devin_cli-1.2.0}/CHANGELOG.md +9 -0
  2. {devin_cli-1.1.9 → devin_cli-1.2.0}/PKG-INFO +1 -1
  3. {devin_cli-1.1.9 → devin_cli-1.2.0}/pyproject.toml +1 -1
  4. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v1/sessions.py +12 -8
  5. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/cli.py +42 -8
  6. {devin_cli-1.1.9 → devin_cli-1.2.0}/.github/workflows/pypi-publish.yml +0 -0
  7. {devin_cli-1.1.9 → devin_cli-1.2.0}/.gitignore +0 -0
  8. {devin_cli-1.1.9 → devin_cli-1.2.0}/LICENSE +0 -0
  9. {devin_cli-1.1.9 → devin_cli-1.2.0}/README.md +0 -0
  10. {devin_cli-1.1.9 → devin_cli-1.2.0}/assets/logo.png +0 -0
  11. {devin_cli-1.1.9 → devin_cli-1.2.0}/generate_facades.py +0 -0
  12. {devin_cli-1.1.9 → devin_cli-1.2.0}/setup.py +0 -0
  13. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/__init__.py +0 -0
  14. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/__init__.py +0 -0
  15. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/attachments.py +0 -0
  16. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/client.py +0 -0
  17. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/consumption.py +0 -0
  18. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/knowledge.py +0 -0
  19. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/members.py +0 -0
  20. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/organizations.py +0 -0
  21. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/playbooks.py +0 -0
  22. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/repositories.py +0 -0
  23. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/schedules.py +0 -0
  24. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/secrets.py +0 -0
  25. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/sessions.py +0 -0
  26. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v1/__init__.py +0 -0
  27. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v1/attachments.py +0 -0
  28. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v1/knowledge.py +0 -0
  29. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v1/playbooks.py +0 -0
  30. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v1/secrets.py +0 -0
  31. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/__init__.py +0 -0
  32. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/attachments.py +0 -0
  33. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/consumption.py +0 -0
  34. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/knowledge.py +0 -0
  35. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/members.py +0 -0
  36. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/organizations.py +0 -0
  37. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/playbooks.py +0 -0
  38. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/repositories.py +0 -0
  39. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/schedules.py +0 -0
  40. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/secrets.py +0 -0
  41. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/api/v3/sessions.py +0 -0
  42. {devin_cli-1.1.9 → devin_cli-1.2.0}/src/devin_cli/config.py +0 -0
  43. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/__init__.py +0 -0
  44. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/conftest.py +0 -0
  45. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_attachments.py +0 -0
  46. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_knowledge.py +0 -0
  47. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_playbooks.py +0 -0
  48. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_repositories.py +0 -0
  49. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_schedules.py +0 -0
  50. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_secrets.py +0 -0
  51. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_api/test_sessions.py +0 -0
  52. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_cli.py +0 -0
  53. {devin_cli-1.1.9 → devin_cli-1.2.0}/tests/test_config.py +0 -0
@@ -5,6 +5,15 @@ 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.2.0] - 2026-03-11
9
+ ### Added
10
+ - `sessions create` / `create-session` now exposes all 8 previously missing v3 API parameters: `--playbook-id`, `--tag`, `--repo`, `--knowledge-id`, `--secret-id`, `--session-link`, `--attachment-url`, `--create-as-user-id`.
11
+ - Profile feedback on session create: prints which profile and API version is being used.
12
+ - Explicit warning when v3-only flags (`--advanced-mode`, `--playbook-id`, `--repo`, `--secret-id`, `--session-link`, `--attachment-url`, `--create-as-user-id`) are passed on a v1 profile — instead of silently ignored.
13
+ ### Fixed
14
+ - Removed `**kwargs` anti-pattern from `v1/sessions.create_session`. Typos in keyword args now raise `TypeError` instead of silently vanishing.
15
+ - v3-only params added as explicit no-ops in v1 `create_session` so the shared CLI call site works without `TypeError`.
16
+
8
17
  ## [1.1.9] - 2026-03-11
9
18
  ### Fixed
10
19
  - `devin watch` terminal status message was printed inside a `Live` context, causing output corruption. Now printed after the `Live` block exits.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devin-cli
3
- Version: 1.1.9
3
+ Version: 1.2.0
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.9"
3
+ version = "1.2.0"
4
4
  description = "Unofficial CLI for Devin AI - The first AI Software Engineer"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,7 +1,7 @@
1
1
  from typing import List, Optional
2
2
  from devin_cli.api.client import client
3
3
 
4
- def list_sessions(limit: int = 100, offset: int = 0, tags: List[str] = None):
4
+ def list_sessions(limit: int = 100, offset: int = 0, tags: Optional[List[str]] = None):
5
5
  params = {"limit": limit, "offset": offset}
6
6
  if tags:
7
7
  params["tags"] = tags
@@ -10,21 +10,25 @@ def list_sessions(limit: int = 100, offset: int = 0, tags: List[str] = None):
10
10
  def create_session(
11
11
  prompt: str,
12
12
  idempotent: bool = False,
13
- snapshot_id: str = None,
14
- playbook_id: str = None,
13
+ snapshot_id: Optional[str] = None,
14
+ playbook_id: Optional[str] = None,
15
15
  unlisted: bool = False,
16
- tags: List[str] = None,
17
- session_secrets: List[dict] = None,
16
+ tags: Optional[List[str]] = None,
17
+ session_secrets: Optional[List[dict]] = None,
18
18
  title: Optional[str] = None,
19
19
  knowledge_ids: Optional[List[str]] = None,
20
20
  secret_ids: Optional[List[str]] = None,
21
21
  max_acu_limit: Optional[int] = None,
22
- **kwargs
22
+ advanced_mode: Optional[str] = None,
23
+ repos: Optional[List[str]] = None,
24
+ session_links: Optional[List[str]] = None,
25
+ attachment_urls: Optional[List[str]] = None,
26
+ create_as_user_id: Optional[str] = None,
23
27
  ):
24
28
  data = {
25
29
  "prompt": prompt,
26
30
  "idempotent": idempotent,
27
- "unlisted": unlisted
31
+ "unlisted": unlisted,
28
32
  }
29
33
  if snapshot_id:
30
34
  data["snapshot_id"] = snapshot_id
@@ -42,7 +46,7 @@ def create_session(
42
46
  data["secret_ids"] = secret_ids
43
47
  if max_acu_limit:
44
48
  data["max_acu_limit"] = max_acu_limit
45
-
49
+
46
50
  return client.post("sessions", json=data)
47
51
 
48
52
  def get_session(session_id: str):
@@ -155,13 +155,38 @@ def create_session_cmd(
155
155
  title: Optional[str] = typer.Option(None, "--title", "-t", help="Custom session title"),
156
156
  org: Optional[str] = typer.Option(None, "--org", help="Override organization ID"),
157
157
  max_acu: Optional[int] = typer.Option(None, "--max-acu", help="Maximum ACU limit"),
158
- advanced_mode: Optional[str] = typer.Option(None, "--advanced-mode", help="Enable advanced mode (e.g. CLI, browser) for the session"),
158
+ advanced_mode: Optional[str] = typer.Option(None, "--advanced-mode", help="Advanced mode type: 'cli' or 'browser' (v3 only)"),
159
+ playbook_id: Optional[str] = typer.Option(None, "--playbook-id", help="Playbook ID to apply (v3 only)"),
160
+ tags: Optional[List[str]] = typer.Option(None, "--tag", help="Session tags (repeatable)"),
161
+ repos: Optional[List[str]] = typer.Option(None, "--repo", help="Repository URLs to attach (v3 only, repeatable)"),
162
+ knowledge_ids: Optional[List[str]] = typer.Option(None, "--knowledge-id", help="Knowledge IDs to attach (repeatable)"),
163
+ secret_ids: Optional[List[str]] = typer.Option(None, "--secret-id", help="Secret IDs to inject (v3 only, repeatable)"),
164
+ session_links: Optional[List[str]] = typer.Option(None, "--session-link", help="Session URLs to link as context (v3 only, repeatable)"),
165
+ attachment_urls: Optional[List[str]] = typer.Option(None, "--attachment-url", help="Attachment URLs to attach (v3 only, repeatable)"),
166
+ create_as_user_id: Optional[str] = typer.Option(None, "--create-as-user-id", help="Enterprise: create session on behalf of this user ID (v3 only)"),
159
167
  force: bool = typer.Option(False, "--force", help="Force creation even if duplicate prompt is detected"),
160
168
  wait: bool = typer.Option(False, "--wait", "-w", help="Block until the session reaches a terminal status"),
161
169
  interval: int = typer.Option(5, "--interval", help="Polling interval in seconds when --wait is used"),
162
170
  ):
163
171
  """Create a new Devin session."""
164
172
  if org: config.temporary_org_id = org
173
+
174
+ api_ver = config.api_version
175
+ console.print(f"[dim]Using profile: {config.active_profile or 'default'} ({api_ver})[/dim]")
176
+
177
+ v3_only_used = [x for x, v in [
178
+ ("--advanced-mode", advanced_mode),
179
+ ("--playbook-id", playbook_id),
180
+ ("--repos", repos),
181
+ ("--secret-ids", secret_ids),
182
+ ("--session-links", session_links),
183
+ ("--attachment-urls", attachment_urls),
184
+ ("--create-as-user-id", create_as_user_id),
185
+ ] if v]
186
+ if api_ver == "v1" and v3_only_used:
187
+ console.print(f"[bold yellow]Warning:[/bold yellow] The following flags are v3-only and will be ignored on a v1 profile: {', '.join(v3_only_used)}")
188
+ console.print(" Run [bold cyan]devin configure[/bold cyan] to switch to a v3 profile.")
189
+
165
190
  if file:
166
191
  prompt_text = file.read_text()
167
192
  elif prompt:
@@ -169,10 +194,10 @@ def create_session_cmd(
169
194
  else:
170
195
  console.print("[bold red]Error:[/bold red] Must provide prompt or --file")
171
196
  raise typer.Exit(1)
172
-
197
+
173
198
  prompt_hash = hashlib.sha256(prompt_text.encode('utf-8')).hexdigest()
174
199
  existing_sid = config.get_session_by_prompt_hash(prompt_hash)
175
-
200
+
176
201
  if existing_sid and not force:
177
202
  console.print(f"[bold yellow]Duplicate Detected:[/bold yellow] You recently created a session with this exact prompt.")
178
203
  console.print(f"Existing Session ID: [bold cyan]{existing_sid}[/bold cyan]")
@@ -182,13 +207,21 @@ def create_session_cmd(
182
207
 
183
208
  with console.status("[bold green]Creating session...[/bold green]"):
184
209
  resp = sessions.create_session(
185
- prompt=prompt_text,
186
- title=title,
210
+ prompt=prompt_text,
211
+ title=title,
187
212
  max_acu_limit=max_acu,
188
- advanced_mode=advanced_mode
213
+ advanced_mode=advanced_mode,
214
+ playbook_id=playbook_id,
215
+ tags=tags or None,
216
+ repos=repos or None,
217
+ knowledge_ids=knowledge_ids or None,
218
+ secret_ids=secret_ids or None,
219
+ session_links=session_links or None,
220
+ attachment_urls=attachment_urls or None,
221
+ create_as_user_id=create_as_user_id,
189
222
  )
190
223
  sid = resp.get("session_id")
191
-
224
+
192
225
  if "advanced_mode_url" in resp:
193
226
  adv_url = resp["advanced_mode_url"]
194
227
  console.print(f"[bold yellow]Advanced Mode Authorization Required![/bold yellow]")
@@ -197,7 +230,7 @@ def create_session_cmd(
197
230
  if typer.confirm("Open browser now?"):
198
231
  import webbrowser
199
232
  webbrowser.open(adv_url)
200
-
233
+
201
234
  if sid:
202
235
  config.current_session_id = sid
203
236
  config.save_prompt_hash(prompt_hash, sid)
@@ -219,6 +252,7 @@ def create_session_cmd(
219
252
  else:
220
253
  console.print("[yellow]Session created, but no ID returned immediately (awaiting advanced mode setup).[/yellow]")
221
254
 
255
+
222
256
  @session_app.command("list")
223
257
  @handle_api_error
224
258
  def list_sessions_cmd(
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