devin-cli 1.3.6__tar.gz → 1.5.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 (80) hide show
  1. {devin_cli-1.3.6 → devin_cli-1.5.0}/.gitignore +1 -0
  2. {devin_cli-1.3.6 → devin_cli-1.5.0}/CHANGELOG.md +39 -0
  3. {devin_cli-1.3.6 → devin_cli-1.5.0}/PKG-INFO +92 -5
  4. {devin_cli-1.3.6 → devin_cli-1.5.0}/README.md +91 -4
  5. {devin_cli-1.3.6 → devin_cli-1.5.0}/generate_facades.py +7 -1
  6. {devin_cli-1.3.6 → devin_cli-1.5.0}/pyproject.toml +1 -1
  7. devin_cli-1.5.0/src/devin_cli/__init__.py +1 -0
  8. devin_cli-1.5.0/src/devin_cli/api/audit_logs.py +13 -0
  9. devin_cli-1.5.0/src/devin_cli/api/blueprints.py +13 -0
  10. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/client.py +7 -10
  11. devin_cli-1.5.0/src/devin_cli/api/code_scans.py +13 -0
  12. devin_cli-1.5.0/src/devin_cli/api/guardrail_violations.py +13 -0
  13. devin_cli-1.5.0/src/devin_cli/api/ip_access_list.py +13 -0
  14. devin_cli-1.5.0/src/devin_cli/api/pr_reviews.py +13 -0
  15. devin_cli-1.5.0/src/devin_cli/api/queue.py +13 -0
  16. devin_cli-1.5.0/src/devin_cli/api/service_users.py +13 -0
  17. devin_cli-1.5.0/src/devin_cli/api/tags.py +13 -0
  18. devin_cli-1.5.0/src/devin_cli/api/v3/audit_logs.py +20 -0
  19. devin_cli-1.5.0/src/devin_cli/api/v3/blueprints.py +22 -0
  20. devin_cli-1.5.0/src/devin_cli/api/v3/code_scans.py +20 -0
  21. devin_cli-1.5.0/src/devin_cli/api/v3/guardrail_violations.py +34 -0
  22. devin_cli-1.5.0/src/devin_cli/api/v3/ip_access_list.py +18 -0
  23. devin_cli-1.5.0/src/devin_cli/api/v3/pr_reviews.py +32 -0
  24. devin_cli-1.5.0/src/devin_cli/api/v3/queue.py +5 -0
  25. devin_cli-1.5.0/src/devin_cli/api/v3/service_users.py +29 -0
  26. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/sessions.py +24 -1
  27. devin_cli-1.5.0/src/devin_cli/api/v3/tags.py +34 -0
  28. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/cli.py +495 -41
  29. devin_cli-1.5.0/src/devin_cli/config.py +260 -0
  30. devin_cli-1.5.0/tests/conftest.py +15 -0
  31. devin_cli-1.5.0/tests/test_api/test_enterprise_endpoints.py +67 -0
  32. devin_cli-1.5.0/tests/test_api/test_pr_reviews.py +31 -0
  33. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_sessions.py +24 -0
  34. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_cli.py +7 -0
  35. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_cli_extended.py +59 -0
  36. devin_cli-1.5.0/tests/test_cli_global_flags.py +112 -0
  37. devin_cli-1.5.0/tests/test_config.py +194 -0
  38. devin_cli-1.5.0/tests/test_configure.py +102 -0
  39. devin_cli-1.3.6/src/devin_cli/__init__.py +0 -1
  40. devin_cli-1.3.6/src/devin_cli/config.py +0 -153
  41. devin_cli-1.3.6/tests/conftest.py +0 -8
  42. devin_cli-1.3.6/tests/test_config.py +0 -27
  43. {devin_cli-1.3.6 → devin_cli-1.5.0}/.github/workflows/pypi-publish.yml +0 -0
  44. {devin_cli-1.3.6 → devin_cli-1.5.0}/LICENSE +0 -0
  45. {devin_cli-1.3.6 → devin_cli-1.5.0}/assets/logo.png +0 -0
  46. {devin_cli-1.3.6 → devin_cli-1.5.0}/setup.py +0 -0
  47. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/__init__.py +0 -0
  48. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/attachments.py +0 -0
  49. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/consumption.py +0 -0
  50. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/knowledge.py +0 -0
  51. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/members.py +0 -0
  52. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/organizations.py +0 -0
  53. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/playbooks.py +0 -0
  54. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/repositories.py +0 -0
  55. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/schedules.py +0 -0
  56. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/secrets.py +0 -0
  57. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/sessions.py +0 -0
  58. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v1/__init__.py +0 -0
  59. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v1/attachments.py +0 -0
  60. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v1/knowledge.py +0 -0
  61. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v1/playbooks.py +0 -0
  62. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v1/secrets.py +0 -0
  63. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v1/sessions.py +0 -0
  64. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/__init__.py +0 -0
  65. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/attachments.py +0 -0
  66. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/consumption.py +0 -0
  67. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/knowledge.py +0 -0
  68. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/members.py +0 -0
  69. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/organizations.py +0 -0
  70. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/playbooks.py +0 -0
  71. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/repositories.py +0 -0
  72. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/schedules.py +0 -0
  73. {devin_cli-1.3.6 → devin_cli-1.5.0}/src/devin_cli/api/v3/secrets.py +0 -0
  74. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/__init__.py +0 -0
  75. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_attachments.py +0 -0
  76. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_knowledge.py +0 -0
  77. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_playbooks.py +0 -0
  78. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_repositories.py +0 -0
  79. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_schedules.py +0 -0
  80. {devin_cli-1.3.6 → devin_cli-1.5.0}/tests/test_api/test_secrets.py +0 -0
@@ -23,6 +23,7 @@ wheels/
23
23
 
24
24
  # Virtual Environment
25
25
  venv/
26
+ .venv/
26
27
  ENV/
27
28
 
28
29
  # Testing
@@ -5,6 +5,45 @@ 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.5.0] - 2026-09-04
9
+ ### Added
10
+ - **On-the-Fly Configuration & Global CLI Flags**: Root command now supports `--token`, `--org`, `--base-url`, `--api-version`, and `--config-file` flags, allowing complete credential configuration on the fly without writing to disk or modifying saved configs.
11
+ - **Predictable Precedence Resolution**: Formalized resolution order across all authentication paths:
12
+ 1. CLI Flags (`--token`, `--org`, `--base-url`, `--api-version`)
13
+ 2. Environment Variables (`DEVIN_API_TOKEN`, `DEVIN_ORG_ID`, `DEVIN_BASE_URL`, `DEVIN_API_VERSION`)
14
+ 3. Config File Profile (`DEVIN_CONFIG_FILE` or `~/.config/devin/config.json`)
15
+ 4. Defaults (`base_url: https://api.devin.ai/v3`, `api_version: v3`)
16
+ - **Zero Disk Writes / Deferred File Creation**: Initializing `Config` or invoking commands with flags/environment variables never touches the filesystem. Config file/directory creation is deferred strictly to explicit save actions (such as `devin configure`), fully unblocking read-only and ephemeral CI runners.
17
+ - **Non-Interactive `configure` Command**: Added `--yes` / `-y` flag and non-TTY stdin autodetection to `devin configure`. Omitting options in non-interactive mode falls back to default values and credentials instead of aborting.
18
+ - **Dynamic Config File Override**: Full support for `DEVIN_CONFIG_FILE` environment variable and `--config-file` flag to direct the CLI to custom config files.
19
+ - **Thread/Context-Safe Runtime Overrides**: Runtime overrides are stored via `contextvars.ContextVar` and cleanly scoped per invocation with `config.reset_runtime()`.
20
+ - **Pre-flight Validation & Scoping Hints**: `validate_for_api()` validates credentials before network requests and outputs helpful diagnostic hints (`Org ID: ...`) when endpoints require organization scoping.
21
+
22
+ ### Fixed
23
+ - **Sanitized Token and Org Inputs**: Automatic trimming of leading/trailing whitespace and newlines from tokens and organization IDs.
24
+ - **Configure Prompt Bugs**: Fixed an issue where `devin configure` always prompted for API version even when non-interactive, and improved option handling so explicit flags bypass interactive prompts.
25
+
26
+ ## [1.4.0] - 2026-08-01
27
+ ### Added
28
+ - **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`.
29
+ - **Devin PR Reviews**: Added `devin pr-reviews trigger` and `devin pr-reviews get` to trigger and query pull request code reviews.
30
+ - **On-Demand Session Insights**: Added `devin sessions generate-insights <session_id>` (`POST /v3/organizations/{org_id}/sessions/{devin_id}/insights/generate`).
31
+ - **Organization Session Tags**: Added `devin tags list|append|replace|clear` to manage organization session tag policies.
32
+ - **Snapshot Setup / Blueprints**: Added `devin blueprints list|trigger-build|list-builds` to list blueprints and manage snapshot builds.
33
+ - **Enterprise Security & Operations Commands**:
34
+ - `devin enterprise ip-access-list list|add|replace|clear`
35
+ - `devin enterprise guardrails list`
36
+ - `devin enterprise code-scans findings|metrics|remediate`
37
+ - `devin enterprise queue` (health status)
38
+ - `devin enterprise audit-logs list`
39
+ - `devin enterprise service-users list|create-key|rotate-key|revoke-key`
40
+ - **Session Secrets Flag**: Support for `--session-secret KEY=VALUE` on `sessions create` for temporary session secret injection.
41
+
42
+ ### Fixed
43
+ - **Beta Enterprise URL Scoping**: Fixed `client.py` URL builder to avoid force-injecting `/organizations/` into `v3beta1/enterprise/` endpoints.
44
+ - **JSON Schema Output Parsing**: Automatically parse `--structured-output-schema` string payloads into valid JSON schema objects to meet API specifications.
45
+ - **Unified `--json` Handling**: Standardized `--json` flag behavior across all new CLI subcommands and improved Rich console output stream handling in `@handle_api_error`.
46
+
8
47
  ## [1.3.4] - 2026-05-03
9
48
  ### Fixed
10
49
  - **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.5.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
@@ -75,9 +75,13 @@ pip install devin-cli
75
75
 
76
76
  ### 2. Configuration
77
77
  ```bash
78
+ # Interactive setup:
78
79
  devin configure
79
80
  # Paste your API token (apk_... or cog_...) from https://preview.devin.ai/settings
80
81
  # Select API version: v3 (default) or v1 (legacy)
82
+
83
+ # Or non-interactive / CI setup:
84
+ devin configure --token "$DEVIN_API_TOKEN" --org "$DEVIN_ORG_ID" --yes
81
85
  ```
82
86
 
83
87
  ### 3. Your First Session
@@ -108,6 +112,53 @@ devin --profile personal sessions create "Fix the failing tests"
108
112
 
109
113
  Profiles are stored in `~/.config/devin/config.json` — fully isolated including session caches and active session IDs.
110
114
 
115
+ ### Automation & CI / CD
116
+
117
+ `devin-cli` is fully optimized for headless CI/CD runners (GitHub Actions, GitLab CI, Jenkins) and containerized workflows.
118
+
119
+ #### Precedence Resolution
120
+ Credentials and configuration resolve in a strict, predictable order:
121
+ 1. **Global CLI Flags** (`--token`, `--org`, `--base-url`, `--api-version`)
122
+ 2. **Environment Variables** (`DEVIN_API_TOKEN`, `DEVIN_ORG_ID`, `DEVIN_BASE_URL`, `DEVIN_API_VERSION`)
123
+ 3. **Config File** (`DEVIN_CONFIG_FILE` or `~/.config/devin/config.json`)
124
+ 4. **Built-in Defaults** (`base_url: https://api.devin.ai/v3`, `api_version: v3`)
125
+
126
+ #### Ephemeral Runs (Zero Disk Writes)
127
+ In CI pipelines, you do not need to create or write configuration files. Pass credentials via environment variables or root CLI flags:
128
+
129
+ ```bash
130
+ # Option A: Environment variables
131
+ export DEVIN_API_TOKEN="cog_..."
132
+ export DEVIN_ORG_ID="org-..."
133
+ devin repos list --json
134
+
135
+ # Option B: Global CLI flags on-the-fly
136
+ devin --token "$DEVIN_API_TOKEN" --org "$DEVIN_ORG_ID" repos status my-org/my-repo --json
137
+ ```
138
+
139
+ #### Non-Interactive Configuration
140
+ If your pipeline writes a config file, use `--yes` (or run in non-TTY environments) to disable interactive prompts:
141
+
142
+ ```bash
143
+ devin configure \
144
+ --token "$DEVIN_API_TOKEN" \
145
+ --org "$DEVIN_ORG_ID" \
146
+ --base-url https://api.devin.ai/v3 \
147
+ --api-version v3 \
148
+ --yes
149
+ ```
150
+
151
+ #### Custom Config File Path
152
+ Override the default `~/.config/devin/config.json` location:
153
+
154
+ ```bash
155
+ # Via flag
156
+ devin --config-file /tmp/devin-ci.json repos list
157
+
158
+ # Via environment variable
159
+ export DEVIN_CONFIG_FILE=/tmp/devin-ci.json
160
+ ```
161
+
111
162
  ---
112
163
 
113
164
  ## 🤖 All Commands
@@ -162,11 +213,14 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
162
213
  | :--- | :--- | :--- |
163
214
  | `[prompt]` | arg | Task prompt |
164
215
  | `--file`, `-f` | path | Read prompt from file |
165
- | `--title`, `-t` | str | Session title |
216
+ | `--title`, `-t` | str | Custom session title |
217
+ | `--devin-mode`, `--mode`, `--model` | str | Agent mode / model: `normal` \| `fast` \| `lite` \| `ultra` \| `fusion` (v3) |
218
+ | `--platform` | str | VM platform (e.g. `windows`) or outpost pool (v3) |
219
+ | `--resumable` / `--no-resumable` | flag | Preserve session VM state after stopping (v3) |
166
220
  | `--wait`, `-w` | flag | Block until session finishes |
167
221
  | `--interval` | int | Polling interval for `--wait` (default: 5s) |
168
222
  | `--max-acu` | int | ACU spend cap |
169
- | `--force` | flag | Skip duplicate detection |
223
+ | `--force` | flag | Skip duplicate prompt detection |
170
224
  | `--advanced-mode` | str | `analyze` \| `create_playbook` \| `improve_playbook` \| `batch` \| `manage_knowledge` |
171
225
  | `--playbook-id` | str | Playbook to apply (v3) |
172
226
  | `--child-playbook-id` | str | Playbook for each sub-session in `batch` mode (v3) |
@@ -175,9 +229,11 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
175
229
  | `--repo` | str (repeatable) | Repo URLs to attach (v3) |
176
230
  | `--knowledge-id` | str (repeatable) | Knowledge IDs to inject |
177
231
  | `--secret-id` | str (repeatable) | Secret IDs to inject (v3) |
232
+ | `--session-secret` | str (repeatable) | Temporary session secret `KEY=VALUE` (v3) |
178
233
  | `--session-link` | str (repeatable) | Session URLs as context (v3) |
179
234
  | `--attachment-url` | str (repeatable) | Attachment URLs (v3) |
180
235
  | `--structured-output-schema` | str | JSON schema for structured response (v3) |
236
+ | `--structured-output-required` | flag | Require structured output tool call (v3) |
181
237
  | `--create-as-user-id` | str | Enterprise: impersonate a user (v3) |
182
238
  | `--org` | str | Override org ID |
183
239
 
@@ -185,6 +241,7 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
185
241
  ```bash
186
242
  # No browser interaction required
187
243
  devin sessions create \
244
+ --devin-mode fast \
188
245
  --advanced-mode batch \
189
246
  --playbook-id <orchestrator-id> \
190
247
  --child-playbook-id <worker-id> \
@@ -192,6 +249,30 @@ devin sessions create \
192
249
  "Process each file in the attached CSV"
193
250
  ```
194
251
 
252
+ ### PR Reviews (`devin pr-reviews <cmd>`)
253
+
254
+ | Command | Key Flags | Description |
255
+ | :--- | :--- | :--- |
256
+ | `trigger` | `--pr-url` | Trigger a Devin code review for a pull request |
257
+ | `get` | `--pr-url`, `--repo-path`, `--pr-number` | Get latest review status for a pull request |
258
+
259
+ ### Organization Session Tags (`devin tags <cmd>`)
260
+
261
+ | Command | Description |
262
+ | :--- | :--- |
263
+ | `list` | List allowed session tags for the organization |
264
+ | `append` | Append tags to organization allowed list (`--tag`) |
265
+ | `replace` | Replace full set of allowed tags (`--tag`) |
266
+ | `clear` | Clear all allowed tags |
267
+
268
+ ### Snapshot Blueprints (`devin blueprints <cmd>`)
269
+
270
+ | Command | Description |
271
+ | :--- | :--- |
272
+ | `list` | List snapshot blueprints for the organization |
273
+ | `trigger-build` | Trigger a manual snapshot build |
274
+ | `list-builds` | List history of snapshot builds |
275
+
195
276
  ### Knowledge (`devin knowledge <cmd>`)
196
277
 
197
278
  | Command | Description |
@@ -238,12 +319,18 @@ devin sessions create \
238
319
  | `upload <file>` | Upload a file |
239
320
  | `download <id>` | Download an attachment |
240
321
 
241
- ### Enterprise (`devin enterprise <cmd>`)
322
+ ### Enterprise Management (`devin enterprise <cmd>`)
242
323
 
243
- | Command | Description |
324
+ | Command Group / Command | Description |
244
325
  | :--- | :--- |
245
326
  | `whoami` | Show current identity |
246
327
  | `list-orgs` | List accessible organizations |
328
+ | `queue` | Get session queue health status |
329
+ | `audit-logs` | List enterprise audit logs (`--limit`, `--order`) |
330
+ | `ip-access-list` | `list` \| `add` \| `replace` \| `clear` enterprise IP allowlists |
331
+ | `guardrails` | `list` guardrail violations (`--session-id`, `--guardrail-id`) |
332
+ | `code-scans` | `findings` \| `metrics` \| `remediate` code scan findings |
333
+ | `service-users` | `list` service users, `create-key`, `rotate-key`, `revoke-key` |
247
334
 
248
335
  ### Chain (`devin chain`)
249
336
 
@@ -39,9 +39,13 @@ pip install devin-cli
39
39
 
40
40
  ### 2. Configuration
41
41
  ```bash
42
+ # Interactive setup:
42
43
  devin configure
43
44
  # Paste your API token (apk_... or cog_...) from https://preview.devin.ai/settings
44
45
  # Select API version: v3 (default) or v1 (legacy)
46
+
47
+ # Or non-interactive / CI setup:
48
+ devin configure --token "$DEVIN_API_TOKEN" --org "$DEVIN_ORG_ID" --yes
45
49
  ```
46
50
 
47
51
  ### 3. Your First Session
@@ -72,6 +76,53 @@ devin --profile personal sessions create "Fix the failing tests"
72
76
 
73
77
  Profiles are stored in `~/.config/devin/config.json` — fully isolated including session caches and active session IDs.
74
78
 
79
+ ### Automation & CI / CD
80
+
81
+ `devin-cli` is fully optimized for headless CI/CD runners (GitHub Actions, GitLab CI, Jenkins) and containerized workflows.
82
+
83
+ #### Precedence Resolution
84
+ Credentials and configuration resolve in a strict, predictable order:
85
+ 1. **Global CLI Flags** (`--token`, `--org`, `--base-url`, `--api-version`)
86
+ 2. **Environment Variables** (`DEVIN_API_TOKEN`, `DEVIN_ORG_ID`, `DEVIN_BASE_URL`, `DEVIN_API_VERSION`)
87
+ 3. **Config File** (`DEVIN_CONFIG_FILE` or `~/.config/devin/config.json`)
88
+ 4. **Built-in Defaults** (`base_url: https://api.devin.ai/v3`, `api_version: v3`)
89
+
90
+ #### Ephemeral Runs (Zero Disk Writes)
91
+ In CI pipelines, you do not need to create or write configuration files. Pass credentials via environment variables or root CLI flags:
92
+
93
+ ```bash
94
+ # Option A: Environment variables
95
+ export DEVIN_API_TOKEN="cog_..."
96
+ export DEVIN_ORG_ID="org-..."
97
+ devin repos list --json
98
+
99
+ # Option B: Global CLI flags on-the-fly
100
+ devin --token "$DEVIN_API_TOKEN" --org "$DEVIN_ORG_ID" repos status my-org/my-repo --json
101
+ ```
102
+
103
+ #### Non-Interactive Configuration
104
+ If your pipeline writes a config file, use `--yes` (or run in non-TTY environments) to disable interactive prompts:
105
+
106
+ ```bash
107
+ devin configure \
108
+ --token "$DEVIN_API_TOKEN" \
109
+ --org "$DEVIN_ORG_ID" \
110
+ --base-url https://api.devin.ai/v3 \
111
+ --api-version v3 \
112
+ --yes
113
+ ```
114
+
115
+ #### Custom Config File Path
116
+ Override the default `~/.config/devin/config.json` location:
117
+
118
+ ```bash
119
+ # Via flag
120
+ devin --config-file /tmp/devin-ci.json repos list
121
+
122
+ # Via environment variable
123
+ export DEVIN_CONFIG_FILE=/tmp/devin-ci.json
124
+ ```
125
+
75
126
  ---
76
127
 
77
128
  ## 🤖 All Commands
@@ -126,11 +177,14 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
126
177
  | :--- | :--- | :--- |
127
178
  | `[prompt]` | arg | Task prompt |
128
179
  | `--file`, `-f` | path | Read prompt from file |
129
- | `--title`, `-t` | str | Session title |
180
+ | `--title`, `-t` | str | Custom session title |
181
+ | `--devin-mode`, `--mode`, `--model` | str | Agent mode / model: `normal` \| `fast` \| `lite` \| `ultra` \| `fusion` (v3) |
182
+ | `--platform` | str | VM platform (e.g. `windows`) or outpost pool (v3) |
183
+ | `--resumable` / `--no-resumable` | flag | Preserve session VM state after stopping (v3) |
130
184
  | `--wait`, `-w` | flag | Block until session finishes |
131
185
  | `--interval` | int | Polling interval for `--wait` (default: 5s) |
132
186
  | `--max-acu` | int | ACU spend cap |
133
- | `--force` | flag | Skip duplicate detection |
187
+ | `--force` | flag | Skip duplicate prompt detection |
134
188
  | `--advanced-mode` | str | `analyze` \| `create_playbook` \| `improve_playbook` \| `batch` \| `manage_knowledge` |
135
189
  | `--playbook-id` | str | Playbook to apply (v3) |
136
190
  | `--child-playbook-id` | str | Playbook for each sub-session in `batch` mode (v3) |
@@ -139,9 +193,11 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
139
193
  | `--repo` | str (repeatable) | Repo URLs to attach (v3) |
140
194
  | `--knowledge-id` | str (repeatable) | Knowledge IDs to inject |
141
195
  | `--secret-id` | str (repeatable) | Secret IDs to inject (v3) |
196
+ | `--session-secret` | str (repeatable) | Temporary session secret `KEY=VALUE` (v3) |
142
197
  | `--session-link` | str (repeatable) | Session URLs as context (v3) |
143
198
  | `--attachment-url` | str (repeatable) | Attachment URLs (v3) |
144
199
  | `--structured-output-schema` | str | JSON schema for structured response (v3) |
200
+ | `--structured-output-required` | flag | Require structured output tool call (v3) |
145
201
  | `--create-as-user-id` | str | Enterprise: impersonate a user (v3) |
146
202
  | `--org` | str | Override org ID |
147
203
 
@@ -149,6 +205,7 @@ Profiles are stored in `~/.config/devin/config.json` — fully isolated includin
149
205
  ```bash
150
206
  # No browser interaction required
151
207
  devin sessions create \
208
+ --devin-mode fast \
152
209
  --advanced-mode batch \
153
210
  --playbook-id <orchestrator-id> \
154
211
  --child-playbook-id <worker-id> \
@@ -156,6 +213,30 @@ devin sessions create \
156
213
  "Process each file in the attached CSV"
157
214
  ```
158
215
 
216
+ ### PR Reviews (`devin pr-reviews <cmd>`)
217
+
218
+ | Command | Key Flags | Description |
219
+ | :--- | :--- | :--- |
220
+ | `trigger` | `--pr-url` | Trigger a Devin code review for a pull request |
221
+ | `get` | `--pr-url`, `--repo-path`, `--pr-number` | Get latest review status for a pull request |
222
+
223
+ ### Organization Session Tags (`devin tags <cmd>`)
224
+
225
+ | Command | Description |
226
+ | :--- | :--- |
227
+ | `list` | List allowed session tags for the organization |
228
+ | `append` | Append tags to organization allowed list (`--tag`) |
229
+ | `replace` | Replace full set of allowed tags (`--tag`) |
230
+ | `clear` | Clear all allowed tags |
231
+
232
+ ### Snapshot Blueprints (`devin blueprints <cmd>`)
233
+
234
+ | Command | Description |
235
+ | :--- | :--- |
236
+ | `list` | List snapshot blueprints for the organization |
237
+ | `trigger-build` | Trigger a manual snapshot build |
238
+ | `list-builds` | List history of snapshot builds |
239
+
159
240
  ### Knowledge (`devin knowledge <cmd>`)
160
241
 
161
242
  | Command | Description |
@@ -202,12 +283,18 @@ devin sessions create \
202
283
  | `upload <file>` | Upload a file |
203
284
  | `download <id>` | Download an attachment |
204
285
 
205
- ### Enterprise (`devin enterprise <cmd>`)
286
+ ### Enterprise Management (`devin enterprise <cmd>`)
206
287
 
207
- | Command | Description |
288
+ | Command Group / Command | Description |
208
289
  | :--- | :--- |
209
290
  | `whoami` | Show current identity |
210
291
  | `list-orgs` | List accessible organizations |
292
+ | `queue` | Get session queue health status |
293
+ | `audit-logs` | List enterprise audit logs (`--limit`, `--order`) |
294
+ | `ip-access-list` | `list` \| `add` \| `replace` \| `clear` enterprise IP allowlists |
295
+ | `guardrails` | `list` guardrail violations (`--session-id`, `--guardrail-id`) |
296
+ | `code-scans` | `findings` \| `metrics` \| `remediate` code scan findings |
297
+ | `service-users` | `list` service users, `create-key`, `rotate-key`, `revoke-key` |
211
298
 
212
299
  ### Chain (`devin chain`)
213
300
 
@@ -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.5.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.5.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)
@@ -1,16 +1,11 @@
1
1
  import httpx
2
- from devin_cli.config import config
2
+ from devin_cli.config import config, APIError
3
3
  from rich.console import Console
4
4
  import sys
5
5
  from typing import Optional, Any, Dict
6
6
 
7
7
  console = Console()
8
8
 
9
- class APIError(Exception):
10
- def __init__(self, message: str, status_code: Optional[int] = None):
11
- super().__init__(message)
12
- self.status_code = status_code
13
-
14
9
  class BaseClient:
15
10
  def __init__(self):
16
11
  pass
@@ -34,9 +29,7 @@ class BaseClient:
34
29
  return config.base_url.rstrip("/")
35
30
 
36
31
  def _ensure_token(self):
37
- if not self.token:
38
- # Only raise error if meaningful operation is attempted
39
- raise APIError("API token not found. Run 'devin configure' to set your API token.")
32
+ config.validate_for_api()
40
33
 
41
34
  def _handle_response(self, response: httpx.Response) -> Any:
42
35
  try:
@@ -53,6 +46,10 @@ class BaseClient:
53
46
  error_detail = e.response.text.strip()
54
47
 
55
48
  msg_suffix = f"\n Path: {path}"
49
+ if config.org_id:
50
+ msg_suffix += f"\n Org ID: {config.org_id}"
51
+ elif "/organizations/" not in path and not path.startswith("/enterprise"):
52
+ msg_suffix += f"\n Org ID: None (Hint: this endpoint may require --org or DEVIN_ORG_ID)"
56
53
  if error_detail:
57
54
  msg_suffix += f"\n Detail: {error_detail}"
58
55
 
@@ -139,7 +136,7 @@ class V3Client(BaseClient):
139
136
  if endpoint.startswith("v3beta1/"):
140
137
  base = config.base_url.replace("/v3", "").replace("/v2", "").replace("/v1", "").rstrip("/")
141
138
  url = f"{base}/{endpoint}"
142
- if config.org_id and "/organizations/" not in url:
139
+ if config.org_id and "/organizations/" not in url and "/enterprise/" not in url:
143
140
  url = url.replace("v3beta1/", f"v3beta1/organizations/{config.org_id}/")
144
141
  return url
145
142
  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)