rootly-mcp-server 2.0.14__tar.gz → 2.0.15__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 (35) hide show
  1. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/PKG-INFO +121 -44
  2. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/README.md +120 -43
  3. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/pyproject.toml +1 -1
  4. rootly_mcp_server-2.0.15/scripts/setup-hooks.sh +66 -0
  5. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/server.py +1014 -28
  6. rootly_mcp_server-2.0.15/src/rootly_mcp_server/texttest.json +3178 -0
  7. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/integration/local/test_smart_tools.py +134 -1
  8. rootly_mcp_server-2.0.15/tests/unit/test_oncall_handoff.py +70 -0
  9. rootly_mcp_server-2.0.15/tests/unit/test_oncall_metrics.py +344 -0
  10. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/unit/test_tools.py +12 -3
  11. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/uv.lock +1 -1
  12. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/.github/workflows/pypi-release.yml +0 -0
  13. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/.github/workflows/test.yml +0 -0
  14. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/.gitignore +0 -0
  15. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/.semaphore/deploy.yml +0 -0
  16. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/.semaphore/semaphore.yml +0 -0
  17. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/.semaphore/update-task-definition.sh +0 -0
  18. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/Dockerfile +0 -0
  19. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/LICENSE +0 -0
  20. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/rootly-mcp-server-demo.gif +0 -0
  21. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/rootly_openapi.json +0 -0
  22. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/__init__.py +0 -0
  23. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/__main__.py +0 -0
  24. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/client.py +0 -0
  25. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/data/__init__.py +0 -0
  26. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/smart_utils.py +0 -0
  27. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/src/rootly_mcp_server/utils.py +0 -0
  28. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/README.md +0 -0
  29. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/conftest.py +0 -0
  30. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/integration/local/test_basic.py +0 -0
  31. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/integration/remote/test_essential.py +0 -0
  32. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/test_client.py +0 -0
  33. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/unit/test_authentication.py +0 -0
  34. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/unit/test_server.py +0 -0
  35. {rootly_mcp_server-2.0.14 → rootly_mcp_server-2.0.15}/tests/unit/test_smart_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rootly-mcp-server
3
- Version: 2.0.14
3
+ Version: 2.0.15
4
4
  Summary: A Model Context Protocol server for Rootly APIs using OpenAPI spec
5
5
  Project-URL: Homepage, https://github.com/Rootly-AI-Labs/Rootly-MCP-server
6
6
  Project-URL: Issues, https://github.com/Rootly-AI-Labs/Rootly-MCP-server/issues
@@ -63,7 +63,7 @@ Configure your MCP-compatible editor (tested with Cursor) with one of the config
63
63
  "run",
64
64
  "--from",
65
65
  "rootly-mcp-server",
66
- "rootly-mcp-server",
66
+ "rootly-mcp-server"
67
67
  ],
68
68
  "env": {
69
69
  "ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
@@ -83,7 +83,7 @@ Configure your MCP-compatible editor (tested with Cursor) with one of the config
83
83
  "args": [
84
84
  "--from",
85
85
  "rootly-mcp-server",
86
- "rootly-mcp-server",
86
+ "rootly-mcp-server"
87
87
  ],
88
88
  "env": {
89
89
  "ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
@@ -143,46 +143,60 @@ Alternatively, connect directly to our hosted MCP server:
143
143
  - **Dynamic Tool Generation**: Automatically creates MCP resources from Rootly's OpenAPI (Swagger) specification
144
144
  - **Smart Pagination**: Defaults to 10 items per request for incident endpoints to prevent context window overflow
145
145
  - **API Filtering**: Limits exposed API endpoints for security and performance
146
- - **AI-Powered Incident Analysis**: Smart tools that learn from historical incident data
147
- - **`find_related_incidents`**: Uses TF-IDF similarity analysis to find historically similar incidents
146
+ - **Intelligent Incident Analysis**: Smart tools that analyze historical incident data
147
+ - **`find_related_incidents`**: Uses TF-IDF similarity analysis to find historically similar incidents
148
148
  - **`suggest_solutions`**: Mines past incident resolutions to recommend actionable solutions
149
149
  - **MCP Resources**: Exposes incident and team data as structured resources for easy AI reference
150
150
  - **Intelligent Pattern Recognition**: Automatically identifies services, error types, and resolution patterns
151
151
 
152
- ### Whitelisted Endpoints
153
-
154
- By default, the following Rootly API endpoints are exposed to the AI agent (see `allowed_paths` in `src/rootly_mcp_server/server.py`):
155
-
156
- ```
157
- /v1/incidents
158
- /v1/incidents/{incident_id}/alerts
159
- /v1/alerts
160
- /v1/alerts/{alert_id}
161
- /v1/severities
162
- /v1/severities/{severity_id}
163
- /v1/teams
164
- /v1/teams/{team_id}
165
- /v1/services
166
- /v1/services/{service_id}
167
- /v1/functionalities
168
- /v1/functionalities/{functionality_id}
169
- /v1/incident_types
170
- /v1/incident_types/{incident_type_id}
171
- /v1/incident_action_items
172
- /v1/incident_action_items/{incident_action_item_id}
173
- /v1/incidents/{incident_id}/action_items
174
- /v1/workflows
175
- /v1/workflows/{workflow_id}
176
- /v1/workflow_runs
177
- /v1/workflow_runs/{workflow_run_id}
178
- /v1/environments
179
- /v1/environments/{environment_id}
180
- /v1/users
181
- /v1/users/{user_id}
182
- /v1/users/me
183
- /v1/status_pages
184
- /v1/status_pages/{status_page_id}
185
- ```
152
+ ### Available Tools
153
+
154
+ **Alerts**
155
+ - `listIncidentAlerts`
156
+ - `listAlerts`
157
+ - `attachAlert`
158
+ - `createAlert`
159
+
160
+ **Environments**
161
+ - `listEnvironments`
162
+ - `createEnvironment`
163
+
164
+ **Functionalities**
165
+ - `listFunctionalities`
166
+ - `createFunctionality`
167
+
168
+ **Workflows**
169
+ - `listWorkflows`
170
+ - `createWorkflow`
171
+
172
+ **Incidents**
173
+ - `listIncidentActionItems`
174
+ - `createIncidentActionItem`
175
+ - `listIncident_Types`
176
+ - `createIncidentType`
177
+ - `search_incidents`
178
+ - `find_related_incidents`
179
+ - `suggest_solutions`
180
+
181
+ **On-Call**
182
+ - `get_oncall_shift_metrics`
183
+ - `get_oncall_handoff_summary`
184
+ - `get_shift_incidents`
185
+
186
+ **Services & Severities**
187
+ - `listServices`
188
+ - `createService`
189
+ - `listSeverities`
190
+ - `createSeverity`
191
+
192
+ **Teams & Users**
193
+ - `listTeams`
194
+ - `createTeam`
195
+ - `listUsers`
196
+ - `getCurrentUser`
197
+
198
+ **Meta**
199
+ - `list_endpoints`
186
200
 
187
201
  ### Why Path Limiting?
188
202
 
@@ -193,14 +207,14 @@ We limit exposed API paths for two key reasons:
193
207
 
194
208
  To expose additional paths, modify the `allowed_paths` variable in `src/rootly_mcp_server/server.py`.
195
209
 
196
- ### AI-Powered Smart Tools
210
+ ### Smart Analysis Tools
197
211
 
198
212
  The MCP server includes intelligent tools that analyze historical incident data to provide actionable insights:
199
213
 
200
214
  #### `find_related_incidents`
201
- Finds historically similar incidents using machine learning text analysis:
215
+ Finds historically similar incidents using text similarity analysis:
202
216
  ```
203
- find_related_incidents(incident_id="12345", similarity_threshold=0.3, max_results=5)
217
+ find_related_incidents(incident_id="12345", similarity_threshold=0.15, max_results=5)
204
218
  ```
205
219
  - **Input**: Incident ID, similarity threshold (0.0-1.0), max results
206
220
  - **Output**: Similar incidents with confidence scores, matched services, and resolution times
@@ -215,7 +229,7 @@ suggest_solutions(incident_title="Payment API errors", incident_description="Use
215
229
  ```
216
230
  - **Input**: Either incident ID OR title/description text
217
231
  - **Output**: Actionable solution recommendations with confidence scores and time estimates
218
- - **Use Case**: Get AI-powered suggestions based on successful past resolutions
232
+ - **Use Case**: Get intelligent suggestions based on successful past resolutions
219
233
 
220
234
  #### How It Works
221
235
  - **Text Similarity**: Uses TF-IDF vectorization and cosine similarity (scikit-learn)
@@ -232,6 +246,56 @@ For optimal results, ensure your Rootly incidents have descriptive:
232
246
 
233
247
  Example good resolution summary: `"Restarted auth-service, cleared Redis cache, and increased connection pool from 10 to 50"`
234
248
 
249
+ ### On-Call Shift Metrics
250
+
251
+ Get on-call shift metrics for any time period, grouped by user, team, or schedule. Includes primary/secondary role tracking, shift counts, hours, and days on-call.
252
+
253
+ ```
254
+ get_oncall_shift_metrics(
255
+ start_date="2025-10-01",
256
+ end_date="2025-10-31",
257
+ group_by="user"
258
+ )
259
+ ```
260
+
261
+ ### On-Call Handoff Summary
262
+
263
+ Complete handoff: current/next on-call + incidents during shifts.
264
+
265
+ ```python
266
+ # All on-call (any timezone)
267
+ get_oncall_handoff_summary(
268
+ team_ids="team-1,team-2",
269
+ timezone="America/Los_Angeles"
270
+ )
271
+
272
+ # Regional filter - only show APAC on-call during APAC business hours
273
+ get_oncall_handoff_summary(
274
+ timezone="Asia/Tokyo",
275
+ filter_by_region=True
276
+ )
277
+ ```
278
+
279
+ Regional filtering shows only people on-call during business hours (9am-5pm) in the specified timezone.
280
+
281
+ Returns: `schedules` with `current_oncall`, `next_oncall`, and `shift_incidents`
282
+
283
+ ### Shift Incidents
284
+
285
+ Incidents during a time period, with filtering by severity/status/tags.
286
+
287
+ ```python
288
+ get_shift_incidents(
289
+ start_time="2025-10-20T09:00:00Z",
290
+ end_time="2025-10-20T17:00:00Z",
291
+ severity="critical", # optional
292
+ status="resolved", # optional
293
+ tags="database,api" # optional
294
+ )
295
+ ```
296
+
297
+ Returns: `incidents` list + `summary` (counts, avg resolution time, grouping)
298
+
235
299
  ## About Rootly AI Labs
236
300
 
237
301
  This project was developed by [Rootly AI Labs](https://labs.rootly.ai/), where we're building the future of system reliability and operational excellence. As an open-source incubator, we share ideas, experiment, and rapidly prototype solutions that benefit the entire community.
@@ -265,7 +329,20 @@ To add new dependencies during development:
265
329
  uv pip install <package>
266
330
  ```
267
331
 
268
- ### 3. Verify Installation
332
+ ### 3. Set Up Git Hooks (Recommended for Contributors)
333
+
334
+ Install pre-commit hooks to automatically run linting and tests before commits:
335
+
336
+ ```bash
337
+ ./scripts/setup-hooks.sh
338
+ ```
339
+
340
+ This ensures code quality by running:
341
+ - Ruff linting
342
+ - Pyright type checking
343
+ - Unit tests
344
+
345
+ ### 4. Verify Installation
269
346
 
270
347
  The server should now be ready to use with your MCP-compatible editor.
271
348
 
@@ -35,7 +35,7 @@ Configure your MCP-compatible editor (tested with Cursor) with one of the config
35
35
  "run",
36
36
  "--from",
37
37
  "rootly-mcp-server",
38
- "rootly-mcp-server",
38
+ "rootly-mcp-server"
39
39
  ],
40
40
  "env": {
41
41
  "ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
@@ -55,7 +55,7 @@ Configure your MCP-compatible editor (tested with Cursor) with one of the config
55
55
  "args": [
56
56
  "--from",
57
57
  "rootly-mcp-server",
58
- "rootly-mcp-server",
58
+ "rootly-mcp-server"
59
59
  ],
60
60
  "env": {
61
61
  "ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
@@ -115,46 +115,60 @@ Alternatively, connect directly to our hosted MCP server:
115
115
  - **Dynamic Tool Generation**: Automatically creates MCP resources from Rootly's OpenAPI (Swagger) specification
116
116
  - **Smart Pagination**: Defaults to 10 items per request for incident endpoints to prevent context window overflow
117
117
  - **API Filtering**: Limits exposed API endpoints for security and performance
118
- - **AI-Powered Incident Analysis**: Smart tools that learn from historical incident data
119
- - **`find_related_incidents`**: Uses TF-IDF similarity analysis to find historically similar incidents
118
+ - **Intelligent Incident Analysis**: Smart tools that analyze historical incident data
119
+ - **`find_related_incidents`**: Uses TF-IDF similarity analysis to find historically similar incidents
120
120
  - **`suggest_solutions`**: Mines past incident resolutions to recommend actionable solutions
121
121
  - **MCP Resources**: Exposes incident and team data as structured resources for easy AI reference
122
122
  - **Intelligent Pattern Recognition**: Automatically identifies services, error types, and resolution patterns
123
123
 
124
- ### Whitelisted Endpoints
125
-
126
- By default, the following Rootly API endpoints are exposed to the AI agent (see `allowed_paths` in `src/rootly_mcp_server/server.py`):
127
-
128
- ```
129
- /v1/incidents
130
- /v1/incidents/{incident_id}/alerts
131
- /v1/alerts
132
- /v1/alerts/{alert_id}
133
- /v1/severities
134
- /v1/severities/{severity_id}
135
- /v1/teams
136
- /v1/teams/{team_id}
137
- /v1/services
138
- /v1/services/{service_id}
139
- /v1/functionalities
140
- /v1/functionalities/{functionality_id}
141
- /v1/incident_types
142
- /v1/incident_types/{incident_type_id}
143
- /v1/incident_action_items
144
- /v1/incident_action_items/{incident_action_item_id}
145
- /v1/incidents/{incident_id}/action_items
146
- /v1/workflows
147
- /v1/workflows/{workflow_id}
148
- /v1/workflow_runs
149
- /v1/workflow_runs/{workflow_run_id}
150
- /v1/environments
151
- /v1/environments/{environment_id}
152
- /v1/users
153
- /v1/users/{user_id}
154
- /v1/users/me
155
- /v1/status_pages
156
- /v1/status_pages/{status_page_id}
157
- ```
124
+ ### Available Tools
125
+
126
+ **Alerts**
127
+ - `listIncidentAlerts`
128
+ - `listAlerts`
129
+ - `attachAlert`
130
+ - `createAlert`
131
+
132
+ **Environments**
133
+ - `listEnvironments`
134
+ - `createEnvironment`
135
+
136
+ **Functionalities**
137
+ - `listFunctionalities`
138
+ - `createFunctionality`
139
+
140
+ **Workflows**
141
+ - `listWorkflows`
142
+ - `createWorkflow`
143
+
144
+ **Incidents**
145
+ - `listIncidentActionItems`
146
+ - `createIncidentActionItem`
147
+ - `listIncident_Types`
148
+ - `createIncidentType`
149
+ - `search_incidents`
150
+ - `find_related_incidents`
151
+ - `suggest_solutions`
152
+
153
+ **On-Call**
154
+ - `get_oncall_shift_metrics`
155
+ - `get_oncall_handoff_summary`
156
+ - `get_shift_incidents`
157
+
158
+ **Services & Severities**
159
+ - `listServices`
160
+ - `createService`
161
+ - `listSeverities`
162
+ - `createSeverity`
163
+
164
+ **Teams & Users**
165
+ - `listTeams`
166
+ - `createTeam`
167
+ - `listUsers`
168
+ - `getCurrentUser`
169
+
170
+ **Meta**
171
+ - `list_endpoints`
158
172
 
159
173
  ### Why Path Limiting?
160
174
 
@@ -165,14 +179,14 @@ We limit exposed API paths for two key reasons:
165
179
 
166
180
  To expose additional paths, modify the `allowed_paths` variable in `src/rootly_mcp_server/server.py`.
167
181
 
168
- ### AI-Powered Smart Tools
182
+ ### Smart Analysis Tools
169
183
 
170
184
  The MCP server includes intelligent tools that analyze historical incident data to provide actionable insights:
171
185
 
172
186
  #### `find_related_incidents`
173
- Finds historically similar incidents using machine learning text analysis:
187
+ Finds historically similar incidents using text similarity analysis:
174
188
  ```
175
- find_related_incidents(incident_id="12345", similarity_threshold=0.3, max_results=5)
189
+ find_related_incidents(incident_id="12345", similarity_threshold=0.15, max_results=5)
176
190
  ```
177
191
  - **Input**: Incident ID, similarity threshold (0.0-1.0), max results
178
192
  - **Output**: Similar incidents with confidence scores, matched services, and resolution times
@@ -187,7 +201,7 @@ suggest_solutions(incident_title="Payment API errors", incident_description="Use
187
201
  ```
188
202
  - **Input**: Either incident ID OR title/description text
189
203
  - **Output**: Actionable solution recommendations with confidence scores and time estimates
190
- - **Use Case**: Get AI-powered suggestions based on successful past resolutions
204
+ - **Use Case**: Get intelligent suggestions based on successful past resolutions
191
205
 
192
206
  #### How It Works
193
207
  - **Text Similarity**: Uses TF-IDF vectorization and cosine similarity (scikit-learn)
@@ -204,6 +218,56 @@ For optimal results, ensure your Rootly incidents have descriptive:
204
218
 
205
219
  Example good resolution summary: `"Restarted auth-service, cleared Redis cache, and increased connection pool from 10 to 50"`
206
220
 
221
+ ### On-Call Shift Metrics
222
+
223
+ Get on-call shift metrics for any time period, grouped by user, team, or schedule. Includes primary/secondary role tracking, shift counts, hours, and days on-call.
224
+
225
+ ```
226
+ get_oncall_shift_metrics(
227
+ start_date="2025-10-01",
228
+ end_date="2025-10-31",
229
+ group_by="user"
230
+ )
231
+ ```
232
+
233
+ ### On-Call Handoff Summary
234
+
235
+ Complete handoff: current/next on-call + incidents during shifts.
236
+
237
+ ```python
238
+ # All on-call (any timezone)
239
+ get_oncall_handoff_summary(
240
+ team_ids="team-1,team-2",
241
+ timezone="America/Los_Angeles"
242
+ )
243
+
244
+ # Regional filter - only show APAC on-call during APAC business hours
245
+ get_oncall_handoff_summary(
246
+ timezone="Asia/Tokyo",
247
+ filter_by_region=True
248
+ )
249
+ ```
250
+
251
+ Regional filtering shows only people on-call during business hours (9am-5pm) in the specified timezone.
252
+
253
+ Returns: `schedules` with `current_oncall`, `next_oncall`, and `shift_incidents`
254
+
255
+ ### Shift Incidents
256
+
257
+ Incidents during a time period, with filtering by severity/status/tags.
258
+
259
+ ```python
260
+ get_shift_incidents(
261
+ start_time="2025-10-20T09:00:00Z",
262
+ end_time="2025-10-20T17:00:00Z",
263
+ severity="critical", # optional
264
+ status="resolved", # optional
265
+ tags="database,api" # optional
266
+ )
267
+ ```
268
+
269
+ Returns: `incidents` list + `summary` (counts, avg resolution time, grouping)
270
+
207
271
  ## About Rootly AI Labs
208
272
 
209
273
  This project was developed by [Rootly AI Labs](https://labs.rootly.ai/), where we're building the future of system reliability and operational excellence. As an open-source incubator, we share ideas, experiment, and rapidly prototype solutions that benefit the entire community.
@@ -237,7 +301,20 @@ To add new dependencies during development:
237
301
  uv pip install <package>
238
302
  ```
239
303
 
240
- ### 3. Verify Installation
304
+ ### 3. Set Up Git Hooks (Recommended for Contributors)
305
+
306
+ Install pre-commit hooks to automatically run linting and tests before commits:
307
+
308
+ ```bash
309
+ ./scripts/setup-hooks.sh
310
+ ```
311
+
312
+ This ensures code quality by running:
313
+ - Ruff linting
314
+ - Pyright type checking
315
+ - Unit tests
316
+
317
+ ### 4. Verify Installation
241
318
 
242
319
  The server should now be ready to use with your MCP-compatible editor.
243
320
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "rootly-mcp-server"
3
- version = "2.0.14"
3
+ version = "2.0.15"
4
4
  description = "A Model Context Protocol server for Rootly APIs using OpenAPI spec"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -0,0 +1,66 @@
1
+ #!/bin/bash
2
+ # Setup git hooks for this repository
3
+ # Run this script after cloning: ./scripts/setup-hooks.sh
4
+
5
+ set -e
6
+
7
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
8
+ HOOKS_DIR="$REPO_ROOT/.git/hooks"
9
+
10
+ echo "🔧 Setting up git hooks..."
11
+
12
+ # Create pre-commit hook
13
+ cat > "$HOOKS_DIR/pre-commit" << 'EOF'
14
+ #!/bin/bash
15
+ # Pre-commit hook to run linting and type checking
16
+ # This ensures code quality before committing
17
+
18
+ set -e
19
+
20
+ echo "🔍 Running pre-commit checks..."
21
+ echo ""
22
+
23
+ # 1. Ruff linting
24
+ echo "📝 Checking code style with ruff..."
25
+ if ! uv run ruff check .; then
26
+ echo "❌ Ruff linting failed!"
27
+ echo "💡 Try running: uv run ruff check . --fix"
28
+ exit 1
29
+ fi
30
+ echo "✅ Ruff passed!"
31
+ echo ""
32
+
33
+ # 2. Pyright type checking
34
+ echo "🔍 Running type checks with pyright..."
35
+ if ! uv run pyright; then
36
+ echo "❌ Type checking failed!"
37
+ echo "💡 Fix type errors or add type: ignore comments"
38
+ exit 1
39
+ fi
40
+ echo "✅ Pyright passed!"
41
+ echo ""
42
+
43
+ # 3. Run unit tests (quick check)
44
+ echo "🧪 Running unit tests..."
45
+ if ! uv run pytest tests/unit/ -q --tb=line; then
46
+ echo "❌ Tests failed!"
47
+ echo "💡 Fix failing tests before committing"
48
+ exit 1
49
+ fi
50
+ echo "✅ Tests passed!"
51
+ echo ""
52
+
53
+ echo "✅ All pre-commit checks passed! Proceeding with commit..."
54
+ exit 0
55
+ EOF
56
+
57
+ chmod +x "$HOOKS_DIR/pre-commit"
58
+
59
+ echo "✅ Git hooks installed successfully!"
60
+ echo ""
61
+ echo "The following checks will run before every commit:"
62
+ echo " 1. Ruff linting"
63
+ echo " 2. Pyright type checking"
64
+ echo " 3. Unit tests"
65
+ echo ""
66
+ echo "To skip hooks (not recommended): git commit --no-verify"