devin-cli 1.3.6__tar.gz → 1.4.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 (75) hide show
  1. {devin_cli-1.3.6 → devin_cli-1.4.0}/CHANGELOG.md +21 -0
  2. {devin_cli-1.3.6 → devin_cli-1.4.0}/PKG-INFO +41 -5
  3. {devin_cli-1.3.6 → devin_cli-1.4.0}/README.md +40 -4
  4. {devin_cli-1.3.6 → devin_cli-1.4.0}/generate_facades.py +7 -1
  5. {devin_cli-1.3.6 → devin_cli-1.4.0}/pyproject.toml +1 -1
  6. devin_cli-1.4.0/src/devin_cli/__init__.py +1 -0
  7. devin_cli-1.4.0/src/devin_cli/api/audit_logs.py +13 -0
  8. devin_cli-1.4.0/src/devin_cli/api/blueprints.py +13 -0
  9. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/client.py +1 -1
  10. devin_cli-1.4.0/src/devin_cli/api/code_scans.py +13 -0
  11. devin_cli-1.4.0/src/devin_cli/api/guardrail_violations.py +13 -0
  12. devin_cli-1.4.0/src/devin_cli/api/ip_access_list.py +13 -0
  13. devin_cli-1.4.0/src/devin_cli/api/pr_reviews.py +13 -0
  14. devin_cli-1.4.0/src/devin_cli/api/queue.py +13 -0
  15. devin_cli-1.4.0/src/devin_cli/api/service_users.py +13 -0
  16. devin_cli-1.4.0/src/devin_cli/api/tags.py +13 -0
  17. devin_cli-1.4.0/src/devin_cli/api/v3/audit_logs.py +20 -0
  18. devin_cli-1.4.0/src/devin_cli/api/v3/blueprints.py +22 -0
  19. devin_cli-1.4.0/src/devin_cli/api/v3/code_scans.py +20 -0
  20. devin_cli-1.4.0/src/devin_cli/api/v3/guardrail_violations.py +34 -0
  21. devin_cli-1.4.0/src/devin_cli/api/v3/ip_access_list.py +18 -0
  22. devin_cli-1.4.0/src/devin_cli/api/v3/pr_reviews.py +32 -0
  23. devin_cli-1.4.0/src/devin_cli/api/v3/queue.py +5 -0
  24. devin_cli-1.4.0/src/devin_cli/api/v3/service_users.py +29 -0
  25. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/sessions.py +24 -1
  26. devin_cli-1.4.0/src/devin_cli/api/v3/tags.py +34 -0
  27. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/cli.py +384 -10
  28. devin_cli-1.4.0/tests/test_api/test_enterprise_endpoints.py +67 -0
  29. devin_cli-1.4.0/tests/test_api/test_pr_reviews.py +31 -0
  30. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_sessions.py +24 -0
  31. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_cli_extended.py +59 -0
  32. devin_cli-1.3.6/src/devin_cli/__init__.py +0 -1
  33. {devin_cli-1.3.6 → devin_cli-1.4.0}/.github/workflows/pypi-publish.yml +0 -0
  34. {devin_cli-1.3.6 → devin_cli-1.4.0}/.gitignore +0 -0
  35. {devin_cli-1.3.6 → devin_cli-1.4.0}/LICENSE +0 -0
  36. {devin_cli-1.3.6 → devin_cli-1.4.0}/assets/logo.png +0 -0
  37. {devin_cli-1.3.6 → devin_cli-1.4.0}/setup.py +0 -0
  38. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/__init__.py +0 -0
  39. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/attachments.py +0 -0
  40. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/consumption.py +0 -0
  41. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/knowledge.py +0 -0
  42. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/members.py +0 -0
  43. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/organizations.py +0 -0
  44. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/playbooks.py +0 -0
  45. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/repositories.py +0 -0
  46. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/schedules.py +0 -0
  47. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/secrets.py +0 -0
  48. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/sessions.py +0 -0
  49. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v1/__init__.py +0 -0
  50. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v1/attachments.py +0 -0
  51. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v1/knowledge.py +0 -0
  52. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v1/playbooks.py +0 -0
  53. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v1/secrets.py +0 -0
  54. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v1/sessions.py +0 -0
  55. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/__init__.py +0 -0
  56. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/attachments.py +0 -0
  57. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/consumption.py +0 -0
  58. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/knowledge.py +0 -0
  59. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/members.py +0 -0
  60. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/organizations.py +0 -0
  61. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/playbooks.py +0 -0
  62. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/repositories.py +0 -0
  63. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/schedules.py +0 -0
  64. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/api/v3/secrets.py +0 -0
  65. {devin_cli-1.3.6 → devin_cli-1.4.0}/src/devin_cli/config.py +0 -0
  66. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/__init__.py +0 -0
  67. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/conftest.py +0 -0
  68. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_attachments.py +0 -0
  69. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_knowledge.py +0 -0
  70. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_playbooks.py +0 -0
  71. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_repositories.py +0 -0
  72. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_schedules.py +0 -0
  73. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_api/test_secrets.py +0 -0
  74. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_cli.py +0 -0
  75. {devin_cli-1.3.6 → devin_cli-1.4.0}/tests/test_config.py +0 -0
@@ -5,6 +5,27 @@ 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.4.0] - 2026-08-01
9
+ ### Added
10
+ - **Model Selection & Agent Modes**: Full support for `--devin-mode` / `--mode` / `--model` (`normal`, `fast`, `lite`, `ultra`, `fusion`), `--platform`, `--resumable / --no-resumable`, and `--structured-output-required` on `devin sessions create` and `devin create-session`.
11
+ - **Devin PR Reviews**: Added `devin pr-reviews trigger` and `devin pr-reviews get` to trigger and query pull request code reviews.
12
+ - **On-Demand Session Insights**: Added `devin sessions generate-insights <session_id>` (`POST /v3/organizations/{org_id}/sessions/{devin_id}/insights/generate`).
13
+ - **Organization Session Tags**: Added `devin tags list|append|replace|clear` to manage organization session tag policies.
14
+ - **Snapshot Setup / Blueprints**: Added `devin blueprints list|trigger-build|list-builds` to list blueprints and manage snapshot builds.
15
+ - **Enterprise Security & Operations Commands**:
16
+ - `devin enterprise ip-access-list list|add|replace|clear`
17
+ - `devin enterprise guardrails list`
18
+ - `devin enterprise code-scans findings|metrics|remediate`
19
+ - `devin enterprise queue` (health status)
20
+ - `devin enterprise audit-logs list`
21
+ - `devin enterprise service-users list|create-key|rotate-key|revoke-key`
22
+ - **Session Secrets Flag**: Support for `--session-secret KEY=VALUE` on `sessions create` for temporary session secret injection.
23
+
24
+ ### Fixed
25
+ - **Beta Enterprise URL Scoping**: Fixed `client.py` URL builder to avoid force-injecting `/organizations/` into `v3beta1/enterprise/` endpoints.
26
+ - **JSON Schema Output Parsing**: Automatically parse `--structured-output-schema` string payloads into valid JSON schema objects to meet API specifications.
27
+ - **Unified `--json` Handling**: Standardized `--json` flag behavior across all new CLI subcommands and improved Rich console output stream handling in `@handle_api_error`.
28
+
8
29
  ## [1.3.4] - 2026-05-03
9
30
  ### Fixed
10
31
  - **Scheduled Sessions API**: Updated the `schedules create` and `schedules update` commands to map the old `cron` and `title` fields to the new `frequency` and `name` properties required by the API. Added `schedule_type="recurring"` and fixed the update method to correctly use `PATCH`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devin-cli
3
- Version: 1.3.6
3
+ Version: 1.4.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
@@ -162,11 +162,14 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
162
162
  | :--- | :--- | :--- |
163
163
  | `[prompt]` | arg | Task prompt |
164
164
  | `--file`, `-f` | path | Read prompt from file |
165
- | `--title`, `-t` | str | Session title |
165
+ | `--title`, `-t` | str | Custom session title |
166
+ | `--devin-mode`, `--mode`, `--model` | str | Agent mode / model: `normal` \| `fast` \| `lite` \| `ultra` \| `fusion` (v3) |
167
+ | `--platform` | str | VM platform (e.g. `windows`) or outpost pool (v3) |
168
+ | `--resumable` / `--no-resumable` | flag | Preserve session VM state after stopping (v3) |
166
169
  | `--wait`, `-w` | flag | Block until session finishes |
167
170
  | `--interval` | int | Polling interval for `--wait` (default: 5s) |
168
171
  | `--max-acu` | int | ACU spend cap |
169
- | `--force` | flag | Skip duplicate detection |
172
+ | `--force` | flag | Skip duplicate prompt detection |
170
173
  | `--advanced-mode` | str | `analyze` \| `create_playbook` \| `improve_playbook` \| `batch` \| `manage_knowledge` |
171
174
  | `--playbook-id` | str | Playbook to apply (v3) |
172
175
  | `--child-playbook-id` | str | Playbook for each sub-session in `batch` mode (v3) |
@@ -175,9 +178,11 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
175
178
  | `--repo` | str (repeatable) | Repo URLs to attach (v3) |
176
179
  | `--knowledge-id` | str (repeatable) | Knowledge IDs to inject |
177
180
  | `--secret-id` | str (repeatable) | Secret IDs to inject (v3) |
181
+ | `--session-secret` | str (repeatable) | Temporary session secret `KEY=VALUE` (v3) |
178
182
  | `--session-link` | str (repeatable) | Session URLs as context (v3) |
179
183
  | `--attachment-url` | str (repeatable) | Attachment URLs (v3) |
180
184
  | `--structured-output-schema` | str | JSON schema for structured response (v3) |
185
+ | `--structured-output-required` | flag | Require structured output tool call (v3) |
181
186
  | `--create-as-user-id` | str | Enterprise: impersonate a user (v3) |
182
187
  | `--org` | str | Override org ID |
183
188
 
@@ -185,6 +190,7 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
185
190
  ```bash
186
191
  # No browser interaction required
187
192
  devin sessions create \
193
+ --devin-mode fast \
188
194
  --advanced-mode batch \
189
195
  --playbook-id <orchestrator-id> \
190
196
  --child-playbook-id <worker-id> \
@@ -192,6 +198,30 @@ devin sessions create \
192
198
  "Process each file in the attached CSV"
193
199
  ```
194
200
 
201
+ ### PR Reviews (`devin pr-reviews <cmd>`)
202
+
203
+ | Command | Key Flags | Description |
204
+ | :--- | :--- | :--- |
205
+ | `trigger` | `--pr-url` | Trigger a Devin code review for a pull request |
206
+ | `get` | `--pr-url`, `--repo-path`, `--pr-number` | Get latest review status for a pull request |
207
+
208
+ ### Organization Session Tags (`devin tags <cmd>`)
209
+
210
+ | Command | Description |
211
+ | :--- | :--- |
212
+ | `list` | List allowed session tags for the organization |
213
+ | `append` | Append tags to organization allowed list (`--tag`) |
214
+ | `replace` | Replace full set of allowed tags (`--tag`) |
215
+ | `clear` | Clear all allowed tags |
216
+
217
+ ### Snapshot Blueprints (`devin blueprints <cmd>`)
218
+
219
+ | Command | Description |
220
+ | :--- | :--- |
221
+ | `list` | List snapshot blueprints for the organization |
222
+ | `trigger-build` | Trigger a manual snapshot build |
223
+ | `list-builds` | List history of snapshot builds |
224
+
195
225
  ### Knowledge (`devin knowledge <cmd>`)
196
226
 
197
227
  | Command | Description |
@@ -238,12 +268,18 @@ devin sessions create \
238
268
  | `upload <file>` | Upload a file |
239
269
  | `download <id>` | Download an attachment |
240
270
 
241
- ### Enterprise (`devin enterprise <cmd>`)
271
+ ### Enterprise Management (`devin enterprise <cmd>`)
242
272
 
243
- | Command | Description |
273
+ | Command Group / Command | Description |
244
274
  | :--- | :--- |
245
275
  | `whoami` | Show current identity |
246
276
  | `list-orgs` | List accessible organizations |
277
+ | `queue` | Get session queue health status |
278
+ | `audit-logs` | List enterprise audit logs (`--limit`, `--order`) |
279
+ | `ip-access-list` | `list` \| `add` \| `replace` \| `clear` enterprise IP allowlists |
280
+ | `guardrails` | `list` guardrail violations (`--session-id`, `--guardrail-id`) |
281
+ | `code-scans` | `findings` \| `metrics` \| `remediate` code scan findings |
282
+ | `service-users` | `list` service users, `create-key`, `rotate-key`, `revoke-key` |
247
283
 
248
284
  ### Chain (`devin chain`)
249
285
 
@@ -126,11 +126,14 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
126
126
  | :--- | :--- | :--- |
127
127
  | `[prompt]` | arg | Task prompt |
128
128
  | `--file`, `-f` | path | Read prompt from file |
129
- | `--title`, `-t` | str | Session title |
129
+ | `--title`, `-t` | str | Custom session title |
130
+ | `--devin-mode`, `--mode`, `--model` | str | Agent mode / model: `normal` \| `fast` \| `lite` \| `ultra` \| `fusion` (v3) |
131
+ | `--platform` | str | VM platform (e.g. `windows`) or outpost pool (v3) |
132
+ | `--resumable` / `--no-resumable` | flag | Preserve session VM state after stopping (v3) |
130
133
  | `--wait`, `-w` | flag | Block until session finishes |
131
134
  | `--interval` | int | Polling interval for `--wait` (default: 5s) |
132
135
  | `--max-acu` | int | ACU spend cap |
133
- | `--force` | flag | Skip duplicate detection |
136
+ | `--force` | flag | Skip duplicate prompt detection |
134
137
  | `--advanced-mode` | str | `analyze` \| `create_playbook` \| `improve_playbook` \| `batch` \| `manage_knowledge` |
135
138
  | `--playbook-id` | str | Playbook to apply (v3) |
136
139
  | `--child-playbook-id` | str | Playbook for each sub-session in `batch` mode (v3) |
@@ -139,9 +142,11 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
139
142
  | `--repo` | str (repeatable) | Repo URLs to attach (v3) |
140
143
  | `--knowledge-id` | str (repeatable) | Knowledge IDs to inject |
141
144
  | `--secret-id` | str (repeatable) | Secret IDs to inject (v3) |
145
+ | `--session-secret` | str (repeatable) | Temporary session secret `KEY=VALUE` (v3) |
142
146
  | `--session-link` | str (repeatable) | Session URLs as context (v3) |
143
147
  | `--attachment-url` | str (repeatable) | Attachment URLs (v3) |
144
148
  | `--structured-output-schema` | str | JSON schema for structured response (v3) |
149
+ | `--structured-output-required` | flag | Require structured output tool call (v3) |
145
150
  | `--create-as-user-id` | str | Enterprise: impersonate a user (v3) |
146
151
  | `--org` | str | Override org ID |
147
152
 
@@ -149,6 +154,7 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
149
154
  ```bash
150
155
  # No browser interaction required
151
156
  devin sessions create \
157
+ --devin-mode fast \
152
158
  --advanced-mode batch \
153
159
  --playbook-id <orchestrator-id> \
154
160
  --child-playbook-id <worker-id> \
@@ -156,6 +162,30 @@ devin sessions create \
156
162
  "Process each file in the attached CSV"
157
163
  ```
158
164
 
165
+ ### PR Reviews (`devin pr-reviews <cmd>`)
166
+
167
+ | Command | Key Flags | Description |
168
+ | :--- | :--- | :--- |
169
+ | `trigger` | `--pr-url` | Trigger a Devin code review for a pull request |
170
+ | `get` | `--pr-url`, `--repo-path`, `--pr-number` | Get latest review status for a pull request |
171
+
172
+ ### Organization Session Tags (`devin tags <cmd>`)
173
+
174
+ | Command | Description |
175
+ | :--- | :--- |
176
+ | `list` | List allowed session tags for the organization |
177
+ | `append` | Append tags to organization allowed list (`--tag`) |
178
+ | `replace` | Replace full set of allowed tags (`--tag`) |
179
+ | `clear` | Clear all allowed tags |
180
+
181
+ ### Snapshot Blueprints (`devin blueprints <cmd>`)
182
+
183
+ | Command | Description |
184
+ | :--- | :--- |
185
+ | `list` | List snapshot blueprints for the organization |
186
+ | `trigger-build` | Trigger a manual snapshot build |
187
+ | `list-builds` | List history of snapshot builds |
188
+
159
189
  ### Knowledge (`devin knowledge <cmd>`)
160
190
 
161
191
  | Command | Description |
@@ -202,12 +232,18 @@ devin sessions create \
202
232
  | `upload <file>` | Upload a file |
203
233
  | `download <id>` | Download an attachment |
204
234
 
205
- ### Enterprise (`devin enterprise <cmd>`)
235
+ ### Enterprise Management (`devin enterprise <cmd>`)
206
236
 
207
- | Command | Description |
237
+ | Command Group / Command | Description |
208
238
  | :--- | :--- |
209
239
  | `whoami` | Show current identity |
210
240
  | `list-orgs` | List accessible organizations |
241
+ | `queue` | Get session queue health status |
242
+ | `audit-logs` | List enterprise audit logs (`--limit`, `--order`) |
243
+ | `ip-access-list` | `list` \| `add` \| `replace` \| `clear` enterprise IP allowlists |
244
+ | `guardrails` | `list` guardrail violations (`--session-id`, `--guardrail-id`) |
245
+ | `code-scans` | `findings` \| `metrics` \| `remediate` code scan findings |
246
+ | `service-users` | `list` service users, `create-key`, `rotate-key`, `revoke-key` |
211
247
 
212
248
  ### Chain (`devin chain`)
213
249
 
@@ -1,6 +1,11 @@
1
1
  import os
2
2
 
3
- modules = ["attachments", "consumption", "knowledge", "members", "organizations", "playbooks", "repositories", "schedules", "secrets", "sessions"]
3
+ modules = [
4
+ "attachments", "consumption", "knowledge", "members", "organizations",
5
+ "playbooks", "repositories", "schedules", "secrets", "sessions",
6
+ "pr_reviews", "tags", "blueprints", "ip_access_list", "guardrail_violations",
7
+ "code_scans", "queue", "audit_logs", "service_users"
8
+ ]
4
9
 
5
10
  for mod in modules:
6
11
  content = f"""from devin_cli.config import config
@@ -19,3 +24,4 @@ def __getattr__(name):
19
24
  """
20
25
  with open(f"src/devin_cli/api/{mod}.py", "w") as f:
21
26
  f.write(content)
27
+
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devin-cli"
3
- version = "1.3.6"
3
+ version = "1.4.0"
4
4
  description = "Unofficial CLI for Devin AI - The first AI Software Engineer"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -0,0 +1 @@
1
+ __version__ = "1.4.0"
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.audit_logs")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'audit_logs' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.audit_logs")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.blueprints")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'blueprints' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.blueprints")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -139,7 +139,7 @@ class V3Client(BaseClient):
139
139
  if endpoint.startswith("v3beta1/"):
140
140
  base = config.base_url.replace("/v3", "").replace("/v2", "").replace("/v1", "").rstrip("/")
141
141
  url = f"{base}/{endpoint}"
142
- if config.org_id and "/organizations/" not in url:
142
+ if config.org_id and "/organizations/" not in url and "/enterprise/" not in url:
143
143
  url = url.replace("v3beta1/", f"v3beta1/organizations/{config.org_id}/")
144
144
  return url
145
145
  elif endpoint.startswith("enterprise/"):
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.code_scans")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'code_scans' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.code_scans")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.guardrail_violations")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'guardrail_violations' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.guardrail_violations")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.ip_access_list")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'ip_access_list' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.ip_access_list")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.pr_reviews")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'pr_reviews' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.pr_reviews")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.queue")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'queue' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.queue")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.service_users")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'service_users' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.service_users")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,13 @@
1
+ from devin_cli.config import config
2
+ import importlib
3
+
4
+ def _get_impl():
5
+ if config.api_version == "v1":
6
+ try:
7
+ return importlib.import_module(f"devin_cli.api.v1.tags")
8
+ except ImportError:
9
+ raise NotImplementedError(f"'tags' feature is only available in Devin API v3, or is not implemented for v1. Run 'devin configure' to switch your API version to v3.")
10
+ return importlib.import_module(f"devin_cli.api.v3.tags")
11
+
12
+ def __getattr__(name):
13
+ return getattr(_get_impl(), name)
@@ -0,0 +1,20 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_audit_logs(limit: int = 100, after: Optional[str] = None, order: Optional[str] = "desc"):
5
+ """List enterprise audit logs."""
6
+ params = {"limit": limit}
7
+ if after:
8
+ params["after"] = after
9
+ if order:
10
+ params["order"] = order
11
+ return client.get("enterprise/audit-logs", params=params)
12
+
13
+ def list_org_audit_logs(limit: int = 100, after: Optional[str] = None, order: Optional[str] = "desc"):
14
+ """List organization audit logs."""
15
+ params = {"limit": limit}
16
+ if after:
17
+ params["after"] = after
18
+ if order:
19
+ params["order"] = order
20
+ return client.get("audit-logs", params=params)
@@ -0,0 +1,22 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_blueprints():
5
+ """List blueprints for organization."""
6
+ return client.get("blueprints")
7
+
8
+ def get_blueprint(blueprint_id: str):
9
+ """Get blueprint by ID."""
10
+ return client.get(f"blueprints/{blueprint_id}")
11
+
12
+ def trigger_build():
13
+ """Trigger a manual snapshot build for the organization."""
14
+ return client.post("builds")
15
+
16
+ def list_builds():
17
+ """List snapshot builds for the organization."""
18
+ return client.get("builds")
19
+
20
+ def get_build(build_id: str):
21
+ """Get snapshot build details."""
22
+ return client.get(f"builds/{build_id}")
@@ -0,0 +1,20 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_code_scan_findings(limit: int = 100, after: Optional[str] = None):
5
+ """List enterprise code scan findings."""
6
+ params = {"limit": limit}
7
+ if after:
8
+ params["after"] = after
9
+ return client.get("v3beta1/enterprise/code-scans/findings", params=params)
10
+
11
+ def get_code_scan_metrics():
12
+ """Get metrics for enterprise code scans."""
13
+ return client.get("v3beta1/enterprise/code-scans/metrics")
14
+
15
+ def remediate_code_scan_finding(finding_id: str, prompt_override: Optional[str] = None):
16
+ """Launch a Devin session to remediate a code scan finding."""
17
+ data = {"finding_id": finding_id}
18
+ if prompt_override:
19
+ data["prompt_override"] = prompt_override
20
+ return client.post("v3beta1/enterprise/code-scans/remediate", json=data)
@@ -0,0 +1,34 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_guardrail_violations(
5
+ limit: int = 100,
6
+ after: Optional[str] = None,
7
+ session_id: Optional[str] = None,
8
+ guardrail_id: Optional[str] = None,
9
+ ):
10
+ """List enterprise guardrail violations."""
11
+ params = {"limit": limit}
12
+ if after:
13
+ params["after"] = after
14
+ if session_id:
15
+ params["session_id"] = session_id
16
+ if guardrail_id:
17
+ params["guardrail_id"] = guardrail_id
18
+ return client.get("v3beta1/enterprise/guardrail-violations", params=params)
19
+
20
+ def list_org_guardrail_violations(
21
+ limit: int = 100,
22
+ after: Optional[str] = None,
23
+ session_id: Optional[str] = None,
24
+ guardrail_id: Optional[str] = None,
25
+ ):
26
+ """List organization guardrail violations."""
27
+ params = {"limit": limit}
28
+ if after:
29
+ params["after"] = after
30
+ if session_id:
31
+ params["session_id"] = session_id
32
+ if guardrail_id:
33
+ params["guardrail_id"] = guardrail_id
34
+ return client.get("v3beta1/guardrail-violations", params=params)
@@ -0,0 +1,18 @@
1
+ from typing import List
2
+ from devin_cli.api.client import client
3
+
4
+ def get_ip_access_list():
5
+ """Get enterprise IP access allowlist."""
6
+ return client.get("enterprise/ip-access-list")
7
+
8
+ def replace_ip_access_list(cidr_blocks: List[str]):
9
+ """Replace entire IP access allowlist."""
10
+ return client.put("enterprise/ip-access-list", json={"ip_ranges": cidr_blocks})
11
+
12
+ def add_ip_access_list(cidr_blocks: List[str]):
13
+ """Append IP ranges to the enterprise IP access allowlist."""
14
+ return client.post("enterprise/ip-access-list", json={"ip_ranges": cidr_blocks})
15
+
16
+ def clear_ip_access_list():
17
+ """Clear enterprise IP access allowlist."""
18
+ return client.delete("enterprise/ip-access-list")
@@ -0,0 +1,32 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def trigger_pr_review(pr_url: str):
5
+ """Trigger a Devin Review for a pull request."""
6
+ return client.post("pr-reviews", json={"pr_url": pr_url})
7
+
8
+ def get_pr_review_status(pr_url: Optional[str] = None, repo_path: Optional[str] = None, pr_number: Optional[int] = None):
9
+ """Get latest Devin Review status for a PR."""
10
+ params = {}
11
+ if pr_url:
12
+ params["pr_url"] = pr_url
13
+ if repo_path:
14
+ params["repo_path"] = repo_path
15
+ if pr_number:
16
+ params["pr_number"] = pr_number
17
+ return client.get("pr-reviews", params=params)
18
+
19
+ def trigger_enterprise_pr_review(pr_url: str):
20
+ """Trigger an enterprise-scoped Devin Review."""
21
+ return client.post("enterprise/pr-reviews", json={"pr_url": pr_url})
22
+
23
+ def get_enterprise_pr_review_status(pr_url: Optional[str] = None, repo_path: Optional[str] = None, pr_number: Optional[int] = None):
24
+ """Get latest enterprise-scoped Devin Review status."""
25
+ params = {}
26
+ if pr_url:
27
+ params["pr_url"] = pr_url
28
+ if repo_path:
29
+ params["repo_path"] = repo_path
30
+ if pr_number:
31
+ params["pr_number"] = pr_number
32
+ return client.get("enterprise/pr-reviews", params=params)
@@ -0,0 +1,5 @@
1
+ from devin_cli.api.client import client
2
+
3
+ def get_queue_status():
4
+ """Get the queue status for an enterprise."""
5
+ return client.get("enterprise/queue")
@@ -0,0 +1,29 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_service_users(limit: int = 100, after: Optional[str] = None):
5
+ """List service users in the enterprise."""
6
+ params = {"limit": limit}
7
+ if after:
8
+ params["after"] = after
9
+ return client.get("enterprise/service-users", params=params)
10
+
11
+ def get_service_user(service_user_id: str):
12
+ """Get service user details."""
13
+ return client.get(f"enterprise/service-users/{service_user_id}")
14
+
15
+ def list_service_user_api_keys(service_user_id: str):
16
+ """List API keys for a service user."""
17
+ return client.get(f"enterprise/service-users/{service_user_id}/api-keys")
18
+
19
+ def create_service_user_api_key(service_user_id: str, name: str):
20
+ """Create a new API key for a service user."""
21
+ return client.post(f"enterprise/service-users/{service_user_id}/api-keys", json={"name": name})
22
+
23
+ def rotate_service_user_api_key(service_user_id: str, key_id: str):
24
+ """Rotate an API key for a service user."""
25
+ return client.post(f"enterprise/service-users/{service_user_id}/api-keys/{key_id}/rotate")
26
+
27
+ def revoke_service_user_api_key(service_user_id: str, key_id: str):
28
+ """Revoke an API key for a service user."""
29
+ return client.delete(f"enterprise/service-users/{service_user_id}/api-keys/{key_id}")
@@ -9,7 +9,11 @@ def list_sessions(limit: int = 100, after: Optional[str] = None):
9
9
 
10
10
  def create_session(
11
11
  prompt: str,
12
+ devin_mode: Optional[str] = None,
12
13
  advanced_mode: Optional[str] = None,
14
+ platform: Optional[str] = None,
15
+ resumable: Optional[bool] = None,
16
+ structured_output_required: Optional[bool] = None,
13
17
  attachment_urls: Optional[List[str]] = None,
14
18
  bypass_approval: bool = False,
15
19
  knowledge_ids: Optional[List[str]] = None,
@@ -28,10 +32,18 @@ def create_session(
28
32
  data = {
29
33
  "prompt": prompt,
30
34
  }
35
+ if devin_mode:
36
+ data["devin_mode"] = devin_mode
31
37
  if bypass_approval:
32
38
  data["bypass_approval"] = bypass_approval
33
39
  if advanced_mode:
34
40
  data["advanced_mode"] = advanced_mode
41
+ if platform:
42
+ data["platform"] = platform
43
+ if resumable is not None:
44
+ data["resumable"] = resumable
45
+ if structured_output_required is not None:
46
+ data["structured_output_required"] = structured_output_required
35
47
  if attachment_urls:
36
48
  data["attachment_urls"] = attachment_urls
37
49
  if knowledge_ids:
@@ -57,7 +69,14 @@ def create_session(
57
69
  if create_as_user_id:
58
70
  data["create_as_user_id"] = create_as_user_id
59
71
  if structured_output_schema:
60
- data["structured_output_schema"] = structured_output_schema
72
+ if isinstance(structured_output_schema, str):
73
+ import json
74
+ try:
75
+ data["structured_output_schema"] = json.loads(structured_output_schema)
76
+ except Exception:
77
+ data["structured_output_schema"] = structured_output_schema
78
+ else:
79
+ data["structured_output_schema"] = structured_output_schema
61
80
 
62
81
  return client.post("sessions", json=data)
63
82
 
@@ -110,3 +129,7 @@ def list_sessions_with_insights(limit: int = 100, after: Optional[str] = None):
110
129
 
111
130
  def get_session_insights(session_id: str):
112
131
  return client.get(f"sessions/{session_id}/insights")
132
+
133
+ def generate_session_insights(session_id: str):
134
+ return client.post(f"sessions/{session_id}/insights/generate")
135
+