devin-cli 0.1.2__tar.gz → 1.0.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 (42) hide show
  1. devin_cli-1.0.0/PKG-INFO +161 -0
  2. devin_cli-1.0.0/README.md +125 -0
  3. {devin_cli-0.1.2 → devin_cli-1.0.0}/pyproject.toml +1 -1
  4. {devin_cli-0.1.2 → devin_cli-1.0.0}/src/devin_cli/api/attachments.py +4 -0
  5. {devin_cli-0.1.2 → devin_cli-1.0.0}/src/devin_cli/api/client.py +47 -27
  6. devin_cli-1.0.0/src/devin_cli/api/consumption.py +22 -0
  7. devin_cli-1.0.0/src/devin_cli/api/knowledge.py +43 -0
  8. devin_cli-1.0.0/src/devin_cli/api/members.py +10 -0
  9. devin_cli-1.0.0/src/devin_cli/api/organizations.py +9 -0
  10. devin_cli-1.0.0/src/devin_cli/api/playbooks.py +53 -0
  11. devin_cli-1.0.0/src/devin_cli/api/repositories.py +44 -0
  12. devin_cli-1.0.0/src/devin_cli/api/schedules.py +60 -0
  13. {devin_cli-0.1.2 → devin_cli-1.0.0}/src/devin_cli/api/secrets.py +3 -0
  14. devin_cli-1.0.0/src/devin_cli/api/sessions.py +93 -0
  15. devin_cli-1.0.0/src/devin_cli/cli.py +457 -0
  16. {devin_cli-0.1.2 → devin_cli-1.0.0}/src/devin_cli/config.py +20 -1
  17. {devin_cli-0.1.2 → devin_cli-1.0.0}/tests/test_api/test_attachments.py +14 -4
  18. {devin_cli-0.1.2 → devin_cli-1.0.0}/tests/test_api/test_knowledge.py +11 -12
  19. {devin_cli-0.1.2 → devin_cli-1.0.0}/tests/test_api/test_playbooks.py +15 -7
  20. devin_cli-1.0.0/tests/test_api/test_repositories.py +33 -0
  21. devin_cli-1.0.0/tests/test_api/test_schedules.py +38 -0
  22. devin_cli-1.0.0/tests/test_api/test_secrets.py +34 -0
  23. devin_cli-1.0.0/tests/test_api/test_sessions.py +69 -0
  24. {devin_cli-0.1.2 → devin_cli-1.0.0}/tests/test_cli.py +3 -4
  25. {devin_cli-0.1.2 → devin_cli-1.0.0}/tests/test_config.py +1 -1
  26. devin_cli-0.1.2/PKG-INFO +0 -282
  27. devin_cli-0.1.2/README.md +0 -246
  28. devin_cli-0.1.2/src/devin_cli/api/knowledge.py +0 -46
  29. devin_cli-0.1.2/src/devin_cli/api/playbooks.py +0 -27
  30. devin_cli-0.1.2/src/devin_cli/api/sessions.py +0 -57
  31. devin_cli-0.1.2/src/devin_cli/cli.py +0 -600
  32. devin_cli-0.1.2/tests/test_api/test_secrets.py +0 -25
  33. devin_cli-0.1.2/tests/test_api/test_sessions.py +0 -59
  34. {devin_cli-0.1.2 → devin_cli-1.0.0}/.github/workflows/pypi-publish.yml +0 -0
  35. {devin_cli-0.1.2 → devin_cli-1.0.0}/.gitignore +0 -0
  36. {devin_cli-0.1.2 → devin_cli-1.0.0}/CHANGELOG.md +0 -0
  37. {devin_cli-0.1.2 → devin_cli-1.0.0}/LICENSE +0 -0
  38. {devin_cli-0.1.2 → devin_cli-1.0.0}/assets/logo.png +0 -0
  39. {devin_cli-0.1.2 → devin_cli-1.0.0}/setup.py +0 -0
  40. {devin_cli-0.1.2 → devin_cli-1.0.0}/src/devin_cli/__init__.py +0 -0
  41. {devin_cli-0.1.2 → devin_cli-1.0.0}/src/devin_cli/api/__init__.py +0 -0
  42. {devin_cli-0.1.2 → devin_cli-1.0.0}/tests/__init__.py +0 -0
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.4
2
+ Name: devin-cli
3
+ Version: 1.0.0
4
+ Summary: Unofficial CLI for Devin AI - The first AI Software Engineer
5
+ Project-URL: Homepage, https://github.com/revanthpobala/devin-cli
6
+ Project-URL: Repository, https://github.com/revanthpobala/devin-cli.git
7
+ Project-URL: Issues, https://github.com/revanthpobala/devin-cli/issues
8
+ Author-email: revanth <revanth@example.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,automation,autonomous,cli,cognition,devin,software-engineer,terminal
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Software Development :: Build Tools
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: httpx>=0.27.0
26
+ Requires-Dist: pyyaml>=6.0
27
+ Requires-Dist: rich>=13.0.0
28
+ Requires-Dist: typer[all]>=0.9.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: build; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
32
+ Requires-Dist: pytest>=7.0; extra == 'dev'
33
+ Requires-Dist: respx>=0.20.0; extra == 'dev'
34
+ Requires-Dist: twine; extra == 'dev'
35
+ Description-Content-Type: text/markdown
36
+
37
+ <p align="center">
38
+ <img src="https://raw.githubusercontent.com/revanthpobala/devin-cli/main/assets/logo.png" alt="Devin CLI Logo" width="300">
39
+ </p>
40
+
41
+ # Devin CLI (Unofficial) — The Professional Terminal Interface for Devin AI
42
+
43
+ <p align="center">
44
+ <a href="https://pypi.org/project/devin-cli/"><img src="https://img.shields.io/pypi/v/devin-cli.svg?style=for-the-badge&color=0294DE" alt="PyPI version"></a>
45
+ <a href="https://github.com/revanthpobala/homebrew-tap"><img src="https://img.shields.io/badge/Homebrew-Tap-orange?style=for-the-badge&logo=homebrew" alt="Homebrew Tap"></a>
46
+ <a href="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml"><img src="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml/badge.svg" alt="Build Status"></a>
47
+ </p>
48
+
49
+ > **The first unofficial CLI for the world's first AI Software Engineer. Now fully upgraded to Devin API v3.**
50
+
51
+ Devin CLI is designed for high-velocity engineering teams. It strips away the friction of the web UI, allowing you to orchestrate autonomous agents, manage complex contexts, and automate multi-step development workflows through a robust, terminal-first interface. Built for performance, SEO, and developer productivity.
52
+
53
+ ---
54
+
55
+ ## ⚡ Quick Start
56
+
57
+ ### 1. Installation
58
+
59
+ **Recommended: Via Homebrew (macOS)**
60
+ ```bash
61
+ brew tap revanthpobala/tap
62
+ brew install devin-cli
63
+ ```
64
+
65
+ **Via pipx (Isolated environment)**
66
+ ```bash
67
+ pipx install devin-cli
68
+ ```
69
+
70
+ **Via pip**
71
+ ```bash
72
+ pip install devin-cli
73
+ ```
74
+
75
+ ### 2. Configuration
76
+ ```bash
77
+ devin configure
78
+ # Paste your v3 API token (apk_... or cog_...) from https://preview.devin.ai/settings
79
+ # Optionally configure your Organization ID here.
80
+ ```
81
+
82
+ ### 3. Your First Session
83
+ ```bash
84
+ devin sessions create -t "Identify and fix the race condition in our Redis cache layer"
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 🛠 Command Cheat Sheet (v3 Architecture)
90
+
91
+ The v3 architecture introduces a modular, hierarchical CLI structure focusing on enterprise features, secrets, and organizational management. Every sub-command supports the `--org` flag to override your active organization on the fly.
92
+
93
+ | Category | Commands | Description |
94
+ | :--- | :--- | :--- |
95
+ | **Sessions** | `create`, `list`, `get`, `insights`, `cost`, `messages`, `message`, `terminate` | Core agent lifecycle and analytics. |
96
+ | **Knowledge** | `list`, `create`, `delete` | Manage organizational context and AI memory. |
97
+ | **Playbooks** | `list`, `create`, `delete` | Automate complex, multi-step agent workflows. |
98
+ | **Secrets** | `list`, `create`, `delete` | Manage API keys passing to Devin sessions. |
99
+ | **Schedules** | `list`, `create` | Schedule recurring autonomous tasks via CRON. |
100
+ | **Repositories** | `list`, `index` | Force indexing of Git repositories. |
101
+ | **Attachments** | `upload`, `download` | Transfer context files seamlessly. |
102
+ | **Enterprise** | `whoami`, `list-orgs` | Administrative identity discovery. |
103
+ | **Global** | `configure`, `use` | CLI setup and active session swapping. |
104
+
105
+ ### Example Automations
106
+
107
+ **Blocking Call for CI/CD:**
108
+ ```bash
109
+ # Trigger Devin and wait for unit tests to be fixed
110
+ devin sessions create "Fix the failing authentication tests"
111
+ echo "Devin finished. Running integration tests..."
112
+ npm test
113
+ ```
114
+
115
+ **Audit Subsystem Costs:**
116
+ ```bash
117
+ # Get ACU consumption for a specific incident
118
+ devin sessions cost --id <SESSION_ID>
119
+ ```
120
+
121
+ ---
122
+
123
+ ## 📟 Integration & Environment Variables
124
+
125
+ Devin CLI is designed for CI/CD. Use environment variables to bypass the `configure` step entirely.
126
+
127
+ - `DEVIN_API_TOKEN`: Your API token.
128
+ - `DEVIN_ORG_ID`: Your target organization ID.
129
+ - `DEVIN_BASE_URL`: (Optional) Overrides the standard `https://api.devin.ai/v3`.
130
+
131
+ ```yaml
132
+ # Example GitHub Action Step
133
+ env:
134
+ DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
135
+ DEVIN_ORG_ID: ${{ secrets.DEVIN_ORG_ID }}
136
+ run: |
137
+ devin sessions create "Review PR #${{ github.event.pull_request.number }}"
138
+ ```
139
+
140
+ ---
141
+
142
+ ## ⚙️ Engineering Specs
143
+ - **Architecture**: Complete Devin API `v3` Support (including `v3beta1` and `enterprise` endpoints).
144
+ - **Config Storage**: `~/.config/devin/config.json`
145
+ - **Platform Support**: Linux, macOS, WSL2
146
+
147
+ ---
148
+
149
+ ## 🧪 Developer Hub
150
+ ```bash
151
+ # Setup
152
+ pip install -e ".[dev]"
153
+
154
+ # Test Suite (100% path coverage)
155
+ PYTHONPATH=src python3 -m pytest
156
+ ```
157
+
158
+ ---
159
+
160
+ ## 📄 License
161
+ MIT. **Devin CLI** is an unofficial community project and is not affiliated with Cognition AI.
@@ -0,0 +1,125 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/revanthpobala/devin-cli/main/assets/logo.png" alt="Devin CLI Logo" width="300">
3
+ </p>
4
+
5
+ # Devin CLI (Unofficial) — The Professional Terminal Interface for Devin AI
6
+
7
+ <p align="center">
8
+ <a href="https://pypi.org/project/devin-cli/"><img src="https://img.shields.io/pypi/v/devin-cli.svg?style=for-the-badge&color=0294DE" alt="PyPI version"></a>
9
+ <a href="https://github.com/revanthpobala/homebrew-tap"><img src="https://img.shields.io/badge/Homebrew-Tap-orange?style=for-the-badge&logo=homebrew" alt="Homebrew Tap"></a>
10
+ <a href="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml"><img src="https://github.com/revanthpobala/devin-cli/actions/workflows/pypi-publish.yml/badge.svg" alt="Build Status"></a>
11
+ </p>
12
+
13
+ > **The first unofficial CLI for the world's first AI Software Engineer. Now fully upgraded to Devin API v3.**
14
+
15
+ Devin CLI is designed for high-velocity engineering teams. It strips away the friction of the web UI, allowing you to orchestrate autonomous agents, manage complex contexts, and automate multi-step development workflows through a robust, terminal-first interface. Built for performance, SEO, and developer productivity.
16
+
17
+ ---
18
+
19
+ ## ⚡ Quick Start
20
+
21
+ ### 1. Installation
22
+
23
+ **Recommended: Via Homebrew (macOS)**
24
+ ```bash
25
+ brew tap revanthpobala/tap
26
+ brew install devin-cli
27
+ ```
28
+
29
+ **Via pipx (Isolated environment)**
30
+ ```bash
31
+ pipx install devin-cli
32
+ ```
33
+
34
+ **Via pip**
35
+ ```bash
36
+ pip install devin-cli
37
+ ```
38
+
39
+ ### 2. Configuration
40
+ ```bash
41
+ devin configure
42
+ # Paste your v3 API token (apk_... or cog_...) from https://preview.devin.ai/settings
43
+ # Optionally configure your Organization ID here.
44
+ ```
45
+
46
+ ### 3. Your First Session
47
+ ```bash
48
+ devin sessions create -t "Identify and fix the race condition in our Redis cache layer"
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 🛠 Command Cheat Sheet (v3 Architecture)
54
+
55
+ The v3 architecture introduces a modular, hierarchical CLI structure focusing on enterprise features, secrets, and organizational management. Every sub-command supports the `--org` flag to override your active organization on the fly.
56
+
57
+ | Category | Commands | Description |
58
+ | :--- | :--- | :--- |
59
+ | **Sessions** | `create`, `list`, `get`, `insights`, `cost`, `messages`, `message`, `terminate` | Core agent lifecycle and analytics. |
60
+ | **Knowledge** | `list`, `create`, `delete` | Manage organizational context and AI memory. |
61
+ | **Playbooks** | `list`, `create`, `delete` | Automate complex, multi-step agent workflows. |
62
+ | **Secrets** | `list`, `create`, `delete` | Manage API keys passing to Devin sessions. |
63
+ | **Schedules** | `list`, `create` | Schedule recurring autonomous tasks via CRON. |
64
+ | **Repositories** | `list`, `index` | Force indexing of Git repositories. |
65
+ | **Attachments** | `upload`, `download` | Transfer context files seamlessly. |
66
+ | **Enterprise** | `whoami`, `list-orgs` | Administrative identity discovery. |
67
+ | **Global** | `configure`, `use` | CLI setup and active session swapping. |
68
+
69
+ ### Example Automations
70
+
71
+ **Blocking Call for CI/CD:**
72
+ ```bash
73
+ # Trigger Devin and wait for unit tests to be fixed
74
+ devin sessions create "Fix the failing authentication tests"
75
+ echo "Devin finished. Running integration tests..."
76
+ npm test
77
+ ```
78
+
79
+ **Audit Subsystem Costs:**
80
+ ```bash
81
+ # Get ACU consumption for a specific incident
82
+ devin sessions cost --id <SESSION_ID>
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 📟 Integration & Environment Variables
88
+
89
+ Devin CLI is designed for CI/CD. Use environment variables to bypass the `configure` step entirely.
90
+
91
+ - `DEVIN_API_TOKEN`: Your API token.
92
+ - `DEVIN_ORG_ID`: Your target organization ID.
93
+ - `DEVIN_BASE_URL`: (Optional) Overrides the standard `https://api.devin.ai/v3`.
94
+
95
+ ```yaml
96
+ # Example GitHub Action Step
97
+ env:
98
+ DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
99
+ DEVIN_ORG_ID: ${{ secrets.DEVIN_ORG_ID }}
100
+ run: |
101
+ devin sessions create "Review PR #${{ github.event.pull_request.number }}"
102
+ ```
103
+
104
+ ---
105
+
106
+ ## ⚙️ Engineering Specs
107
+ - **Architecture**: Complete Devin API `v3` Support (including `v3beta1` and `enterprise` endpoints).
108
+ - **Config Storage**: `~/.config/devin/config.json`
109
+ - **Platform Support**: Linux, macOS, WSL2
110
+
111
+ ---
112
+
113
+ ## 🧪 Developer Hub
114
+ ```bash
115
+ # Setup
116
+ pip install -e ".[dev]"
117
+
118
+ # Test Suite (100% path coverage)
119
+ PYTHONPATH=src python3 -m pytest
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 📄 License
125
+ MIT. **Devin CLI** is an unofficial community project and is not affiliated with Cognition AI.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devin-cli"
3
- version = "0.1.2"
3
+ version = "1.0.0"
4
4
  description = "Unofficial CLI for Devin AI - The first AI Software Engineer"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -9,4 +9,8 @@ def upload_file(file_path: str):
9
9
  with open(path, "rb") as f:
10
10
  files = {"file": f}
11
11
  # client.post handles Content-Type removal for files
12
+ # The client will inject /organizations/{org_id}/ if configured
12
13
  return client.post("attachments", files=files)
14
+
15
+ def download_attachment(uuid: str, name: str):
16
+ return client.get(f"attachments/{uuid}/{name}")
@@ -13,25 +13,21 @@ class APIError(Exception):
13
13
 
14
14
  class APIClient:
15
15
  def __init__(self):
16
- self._token: Optional[str] = None
17
- self._headers: Dict[str, str] = {}
16
+ pass
18
17
 
19
18
  @property
20
19
  def token(self) -> Optional[str]:
21
- if not self._token:
22
- self._token = config.api_token
23
- return self._token
20
+ return config.api_token
24
21
 
25
22
  @property
26
23
  def headers(self) -> Dict[str, str]:
27
- if not self._headers:
28
- t = self.token
29
- if t:
30
- self._headers = {
31
- "Authorization": f"Bearer {t}",
32
- "Content-Type": "application/json",
33
- }
34
- return self._headers
24
+ t = self.token
25
+ headers = {
26
+ "Content-Type": "application/json",
27
+ }
28
+ if t:
29
+ headers["Authorization"] = f"Bearer {t}"
30
+ return headers
35
31
 
36
32
  @property
37
33
  def BASE_URL(self) -> str:
@@ -63,14 +59,38 @@ class APIClient:
63
59
  if response.status_code == 204:
64
60
  return None
65
61
 
66
- try:
67
- return response.json()
68
- except ValueError:
69
- return response.text
62
+ content_type = response.headers.get("Content-Type", "")
63
+ if "application/json" in content_type:
64
+ try:
65
+ return response.json()
66
+ except ValueError:
67
+ return response.text
68
+
69
+ # If it's not JSON, it might be an attachment or raw text
70
+ if any(t in content_type for t in ["image/", "application/octet-stream", "application/pdf"]):
71
+ return response.content
72
+
73
+ return response.text
70
74
 
71
75
  def request(self, method: str, endpoint: str, **kwargs) -> Any:
72
76
  self._ensure_token()
73
- url = f"{self.BASE_URL}/{endpoint.lstrip('/')}"
77
+
78
+ endpoint = endpoint.lstrip("/")
79
+
80
+ # Determine the base URL and whether to inject organization
81
+ if endpoint.startswith("v3beta1/"):
82
+ base = config.base_url.replace("/v3", "").replace("/v2", "").replace("/v1", "").rstrip("/")
83
+ url = f"{base}/{endpoint}"
84
+ # Inject organization for v3beta1 if not present
85
+ if config.org_id and "/organizations/" not in url:
86
+ url = url.replace("v3beta1/", f"v3beta1/organizations/{config.org_id}/")
87
+ elif endpoint.startswith("enterprise/"):
88
+ url = f"{self.BASE_URL}/{endpoint}"
89
+ else:
90
+ # Standard path, inject organization if configured
91
+ if config.org_id and not endpoint.startswith("organizations/"):
92
+ endpoint = f"organizations/{config.org_id}/{endpoint}"
93
+ url = f"{self.BASE_URL}/{endpoint}"
74
94
 
75
95
  # Merge headers if needed, but usually self.headers is enough
76
96
  headers = self.headers.copy()
@@ -82,22 +102,22 @@ class APIClient:
82
102
  headers.pop("Content-Type", None)
83
103
 
84
104
  try:
85
- with httpx.Client() as client:
105
+ with httpx.Client(follow_redirects=True) as client:
86
106
  response = client.request(method, url, headers=headers, **kwargs)
87
107
  return self._handle_response(response)
88
108
  except httpx.RequestError as e:
89
109
  raise APIError(f"Network error: {e}")
90
110
 
91
- def get(self, endpoint: str, params: Optional[Dict] = None) -> Any:
92
- return self.request("GET", endpoint, params=params)
111
+ def get(self, endpoint: str, **kwargs) -> Any:
112
+ return self.request("GET", endpoint, **kwargs)
93
113
 
94
- def post(self, endpoint: str, data: Optional[Dict] = None, files: Optional[Dict] = None) -> Any:
95
- return self.request("POST", endpoint, json=data, files=files)
114
+ def post(self, endpoint: str, **kwargs) -> Any:
115
+ return self.request("POST", endpoint, **kwargs)
96
116
 
97
- def put(self, endpoint: str, data: Optional[Dict] = None) -> Any:
98
- return self.request("PUT", endpoint, json=data)
117
+ def put(self, endpoint: str, **kwargs) -> Any:
118
+ return self.request("PUT", endpoint, **kwargs)
99
119
 
100
- def delete(self, endpoint: str) -> Any:
101
- return self.request("DELETE", endpoint)
120
+ def delete(self, endpoint: str, **kwargs) -> Any:
121
+ return self.request("DELETE", endpoint, **kwargs)
102
122
 
103
123
  client = APIClient()
@@ -0,0 +1,22 @@
1
+ from typing import Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def get_session_consumption(session_id: str):
5
+ """Get daily ACU consumption for a specific session"""
6
+ return client.get(f"enterprise/consumption/daily/sessions/{session_id}")
7
+
8
+ def get_service_user_consumption(service_user_id: str):
9
+ """Get daily ACU consumption for sessions initiated by a service user"""
10
+ return client.get(f"enterprise/consumption/daily/service-users/{service_user_id}")
11
+
12
+ def list_consumption_cycles():
13
+ """List consumption cycles (Enterprise key required)"""
14
+ return client.get("enterprise/consumption/cycles")
15
+
16
+ def get_daily_consumption_breakdown():
17
+ """Get overall daily ACU consumption breakdown"""
18
+ return client.get("enterprise/consumption/daily")
19
+
20
+ def get_acu_limits():
21
+ """Get ACU limits for the organization/enterprise"""
22
+ return client.get("enterprise/consumption/limits")
@@ -0,0 +1,43 @@
1
+ from typing import List, Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_knowledge():
5
+ return client.get("knowledge/notes")
6
+
7
+ def create_knowledge(
8
+ title: str,
9
+ body: str,
10
+ # v3 uses title/body, v1 used name/body/trigger_description
11
+ # We'll map them for compatibility if possible, but v3 is primary
12
+ ):
13
+ data = {
14
+ "title": title,
15
+ "body": body,
16
+ }
17
+ return client.post("knowledge/notes", json=data)
18
+
19
+ def get_knowledge(note_id: str):
20
+ return client.get(f"knowledge/notes/{note_id}")
21
+
22
+ def update_knowledge(
23
+ note_id: str,
24
+ title: Optional[str] = None,
25
+ body: Optional[str] = None,
26
+ ):
27
+ data = {}
28
+ if title:
29
+ data["title"] = title
30
+ if body:
31
+ data["body"] = body
32
+
33
+ return client.put(f"knowledge/notes/{note_id}", json=data)
34
+
35
+ def delete_knowledge(note_id: str):
36
+ return client.delete(f"knowledge/notes/{note_id}")
37
+
38
+ # Enterprise Knowledge
39
+ def list_enterprise_knowledge():
40
+ return client.get("enterprise/knowledge/notes")
41
+
42
+ def get_enterprise_knowledge(note_id: str):
43
+ return client.get(f"enterprise/knowledge/notes/{note_id}")
@@ -0,0 +1,10 @@
1
+ from devin_cli.api.client import client
2
+
3
+ def get_self():
4
+ """Get current authenticated user info (Enterprise context)"""
5
+ # Based on Devin API v3 "Self" category info
6
+ return client.get("enterprise/members/self")
7
+
8
+ def get_user(user_id: str):
9
+ """Get info for a specific user"""
10
+ return client.get(f"enterprise/members/users/{user_id}")
@@ -0,0 +1,9 @@
1
+ from devin_cli.api.client import client
2
+
3
+ def list_organizations():
4
+ """List all organizations (Enterprise key required)"""
5
+ return client.get("enterprise/organizations")
6
+
7
+ def get_organization(org_id: str):
8
+ """Get details of a specific organization (Enterprise key required)"""
9
+ return client.get(f"enterprise/organizations/{org_id}")
@@ -0,0 +1,53 @@
1
+ from typing import List, Optional
2
+ from devin_cli.api.client import client
3
+
4
+ def list_playbooks():
5
+ return client.get("playbooks")
6
+
7
+ def create_playbook(title: str, body: str, macro: Optional[str] = None):
8
+ data = {"title": title, "body": body}
9
+ if macro:
10
+ data["macro"] = macro
11
+ return client.post("playbooks", json=data)
12
+
13
+ def get_playbook(playbook_id: str):
14
+ return client.get(f"playbooks/{playbook_id}")
15
+
16
+ def update_playbook(playbook_id: str, title: Optional[str] = None, body: Optional[str] = None, macro: Optional[str] = None):
17
+ data = {}
18
+ if title:
19
+ data["title"] = title
20
+ if body:
21
+ data["body"] = body
22
+ if macro:
23
+ data["macro"] = macro
24
+ return client.put(f"playbooks/{playbook_id}", json=data)
25
+
26
+ def delete_playbook(playbook_id: str):
27
+ return client.delete(f"playbooks/{playbook_id}")
28
+
29
+ # Enterprise Playbooks
30
+ def list_enterprise_playbooks():
31
+ return client.get("enterprise/playbooks")
32
+
33
+ def create_enterprise_playbook(title: str, body: str, macro: Optional[str] = None):
34
+ data = {"title": title, "body": body}
35
+ if macro:
36
+ data["macro"] = macro
37
+ return client.post("enterprise/playbooks", json=data)
38
+
39
+ def get_enterprise_playbook(playbook_id: str):
40
+ return client.get(f"enterprise/playbooks/{playbook_id}")
41
+
42
+ def update_enterprise_playbook(playbook_id: str, title: Optional[str] = None, body: Optional[str] = None, macro: Optional[str] = None):
43
+ data = {}
44
+ if title:
45
+ data["title"] = title
46
+ if body:
47
+ data["body"] = body
48
+ if macro:
49
+ data["macro"] = macro
50
+ return client.put(f"enterprise/playbooks/{playbook_id}", json=data)
51
+
52
+ def delete_enterprise_playbook(playbook_id: str):
53
+ return client.delete(f"enterprise/playbooks/{playbook_id}")
@@ -0,0 +1,44 @@
1
+ from typing import List, Optional, Union
2
+ from devin_cli.api.client import client
3
+
4
+ def list_repositories(limit: int = 100, after: Optional[str] = None):
5
+ params = {"limit": limit}
6
+ if after:
7
+ params["after"] = after
8
+ return client.get("v3beta1/repositories", params=params)
9
+
10
+ def list_indexed_repositories():
11
+ return client.get("v3beta1/repositories/indexing")
12
+
13
+ def get_indexing_status(repository_path: str):
14
+ """repository_path should be owner/repo"""
15
+ return client.get(f"v3beta1/repositories/{repository_path}/indexing")
16
+
17
+ def index_repository(repository_path: str, branch_name: Optional[str] = None):
18
+ data = {}
19
+ if branch_name:
20
+ data["branch_name"] = branch_name
21
+ return client.put(f"v3beta1/repositories/{repository_path}/indexing", json=data)
22
+
23
+ def index_repositories_bulk(repository_paths: List[str]):
24
+ return client.put("v3beta1/repositories/indexing/bulk", json={"repository_paths": repository_paths})
25
+
26
+ def remove_from_indexing(repository_path: str):
27
+ return client.delete(f"v3beta1/repositories/{repository_path}/indexing")
28
+
29
+ def remove_from_indexing_bulk(repository_paths: List[str]):
30
+ return client.delete("v3beta1/repositories/indexing/bulk", json={"repository_paths": repository_paths})
31
+
32
+ # Enterprise Git Management
33
+ def list_git_connections():
34
+ return client.get("enterprise/git-providers/connections")
35
+
36
+ def list_git_permissions():
37
+ return client.get("enterprise/git-providers/permissions")
38
+
39
+ def create_git_permission(org_id: str, permission: str):
40
+ data = {"org_id": org_id, "permission": permission}
41
+ return client.post("enterprise/git-providers/permissions", json=data)
42
+
43
+ def delete_git_permission(org_id: str):
44
+ return client.delete(f"enterprise/git-providers/permissions", params={"org_id": org_id})
@@ -0,0 +1,60 @@
1
+ from typing import List, Optional, Dict, Any
2
+ from devin_cli.api.client import client
3
+
4
+ def list_schedules(limit: int = 100, after: Optional[str] = None):
5
+ params = {"limit": limit}
6
+ if after:
7
+ params["after"] = after
8
+ return client.get("schedules", params=params)
9
+
10
+ def create_schedule(
11
+ prompt: str,
12
+ cron: str,
13
+ title: Optional[str] = None,
14
+ # Additional v3 parameters
15
+ advanced_mode: Optional[str] = None,
16
+ playbook_id: Optional[str] = None,
17
+ repos: Optional[List[str]] = None,
18
+ tags: Optional[List[str]] = None,
19
+ ):
20
+ data = {
21
+ "prompt": prompt,
22
+ "cron": cron,
23
+ }
24
+ if title:
25
+ data["title"] = title
26
+ if advanced_mode:
27
+ data["advanced_mode"] = advanced_mode
28
+ if playbook_id:
29
+ data["playbook_id"] = playbook_id
30
+ if repos:
31
+ data["repos"] = repos
32
+ if tags:
33
+ data["tags"] = tags
34
+
35
+ return client.post("schedules", json=data)
36
+
37
+ def get_schedule(schedule_id: str):
38
+ return client.get(f"schedules/{schedule_id}")
39
+
40
+ def update_schedule(
41
+ schedule_id: str,
42
+ prompt: Optional[str] = None,
43
+ cron: Optional[str] = None,
44
+ title: Optional[str] = None,
45
+ enabled: Optional[bool] = None,
46
+ ):
47
+ data = {}
48
+ if prompt:
49
+ data["prompt"] = prompt
50
+ if cron:
51
+ data["cron"] = cron
52
+ if title:
53
+ data["title"] = title
54
+ if enabled is not None:
55
+ data["enabled"] = enabled
56
+
57
+ return client.put(f"schedules/{schedule_id}", json=data)
58
+
59
+ def delete_schedule(schedule_id: str):
60
+ return client.delete(f"schedules/{schedule_id}")
@@ -3,5 +3,8 @@ from devin_cli.api.client import client
3
3
  def list_secrets():
4
4
  return client.get("secrets")
5
5
 
6
+ def create_secret(name: str, value: str):
7
+ return client.post("secrets", json={"name": name, "value": value})
8
+
6
9
  def delete_secret(secret_id: str):
7
10
  return client.delete(f"secrets/{secret_id}")