@openhands/extensions 0.22.1 → 0.23.0
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.
- package/.agents/skills/custom-codereview-guide.md +84 -17
- package/.release-please-manifest.json +1 -1
- package/AGENTS.md +22 -1
- package/README.md +1 -1
- package/automations/bundle-index.js +12 -11
- package/automations/catalog/github-issue-triage/manifest.json +2 -2
- package/automations/catalog/github-pr-reviewer/manifest.json +42 -5
- package/automations/catalog.schema.json +0 -4
- package/package.json +1 -1
- package/plugins/openhands/skills/openhands-sdk/SKILL.md +3 -1
- package/plugins/pr-review/README.md +2 -1
- package/plugins/pr-review/scripts/agent_script.py +198 -81
- package/plugins/pr-review/scripts/prompt.py +35 -11
- package/plugins/pr-review/skills/code-review/SKILL.md +165 -200
- package/plugins/pr-review/skills/code-review/commands/codereview-roasted.md +1 -1
- package/plugins/pr-review/skills/code-review/commands/codereview.md +1 -1
- package/plugins/vulnerability-remediation/skills/github/scripts/agent_conversation.py +8 -3
- package/plugins/vulnerability-remediation/skills/github/scripts/github_client.py +4 -0
- package/pyproject.toml +1 -1
- package/python/openhands_extensions/_version.py +1 -1
- package/skills/code-review/SKILL.md +165 -200
- package/skills/code-review/commands/codereview-roasted.md +1 -1
- package/skills/code-review/commands/codereview.md +1 -1
- package/skills/github/scripts/agent_conversation.py +8 -3
- package/skills/github/scripts/github_client.py +4 -0
- package/skills/github-agents-md-maintainer/scripts/github_client.py +4 -0
- package/skills/github-delivery-watchdog/scripts/github_client.py +4 -0
- package/skills/github-issue-to-pr/scripts/agent_conversation.py +8 -3
- package/skills/github-issue-to-pr/scripts/github_client.py +4 -0
- package/skills/github-issue-triage/.claude-plugin/plugin.json +1 -1
- package/skills/github-issue-triage/.codex-plugin/plugin.json +1 -1
- package/skills/github-issue-triage/.plugin/plugin.json +1 -1
- package/skills/github-issue-triage/README.md +7 -0
- package/skills/github-issue-triage/SKILL.md +26 -3
- package/skills/github-issue-triage/scripts/agent_conversation.py +8 -3
- package/skills/github-issue-triage/scripts/github_client.py +4 -0
- package/skills/github-issue-triage/scripts/worker.py +142 -26
- package/skills/github-pr-reviewer/README.md +16 -10
- package/skills/github-pr-reviewer/SKILL.md +12 -9
- package/skills/github-pr-reviewer/commands/pr-reviewer-setup.md +1 -1
- package/skills/github-pr-reviewer/scripts/agent_conversation.py +8 -3
- package/skills/github-pr-reviewer/scripts/github_client.py +4 -0
- package/skills/github-pr-reviewer/scripts/main.py +23 -5
- package/skills/github-pr-reviewer/scripts/maintainer_handoff.py +151 -0
- package/skills/github-pr-reviewer/scripts/worker.py +209 -21
- package/skills/github-pr-reviewer/tests/test_main.py +16 -0
- package/skills/github-repo-monitor/scripts/github_client.py +4 -0
- package/skills/index.js +6 -6
- package/skills/openhands-sdk/SKILL.md +3 -1
- package/tests/fixtures/automations/github-pr-reviewer.json +120 -26
- package/tests/github_automation_helpers.py +1 -0
- package/tests/test_agent_conversation_dispatch.py +19 -4
- package/tests/test_automation_setup.py +15 -0
- package/tests/test_code_review_risk_evaluation.py +2 -2
- package/tests/test_github_reviewer_delivery.py +320 -4
- package/tests/test_github_triage_delivery.py +200 -6
- package/tests/test_maintainer_handoff.py +198 -0
- package/tests/test_pr_review_prompt.py +6 -2
- package/tests/test_pr_review_review_context.py +144 -0
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
"repositories": [
|
|
19
19
|
"OpenHands/agent-server-gui"
|
|
20
20
|
],
|
|
21
|
-
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
21
|
+
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
22
|
+
"maintainers": "",
|
|
23
|
+
"triggerReviewer": "all-hands-bot"
|
|
22
24
|
},
|
|
23
25
|
"upload": {
|
|
24
26
|
"request": {
|
|
@@ -32,6 +34,7 @@
|
|
|
32
34
|
"config.json",
|
|
33
35
|
"main.py",
|
|
34
36
|
"github_client.py",
|
|
37
|
+
"maintainer_handoff.py",
|
|
35
38
|
"worker.py"
|
|
36
39
|
]
|
|
37
40
|
},
|
|
@@ -64,14 +67,16 @@
|
|
|
64
67
|
"timeout": 300,
|
|
65
68
|
"template": {
|
|
66
69
|
"id": "github-pr-reviewer",
|
|
67
|
-
"version": "1.
|
|
70
|
+
"version": "1.3.0",
|
|
68
71
|
"config": {
|
|
69
72
|
"repos": [
|
|
70
73
|
"OpenHands/agent-server-gui"
|
|
71
74
|
],
|
|
72
75
|
"trigger_label": "openhands-review",
|
|
73
76
|
"review_tone": "thorough",
|
|
74
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
77
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
78
|
+
"maintainers": "",
|
|
79
|
+
"trigger_reviewer": "all-hands-bot"
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
}
|
|
@@ -101,14 +106,16 @@
|
|
|
101
106
|
"timeout": 300,
|
|
102
107
|
"template": {
|
|
103
108
|
"id": "github-pr-reviewer",
|
|
104
|
-
"version": "1.
|
|
109
|
+
"version": "1.3.0",
|
|
105
110
|
"config": {
|
|
106
111
|
"repos": [
|
|
107
112
|
"OpenHands/agent-server-gui"
|
|
108
113
|
],
|
|
109
114
|
"trigger_label": "openhands-review",
|
|
110
115
|
"review_tone": "thorough",
|
|
111
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
116
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
117
|
+
"maintainers": "",
|
|
118
|
+
"trigger_reviewer": "all-hands-bot"
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
}
|
|
@@ -138,7 +145,8 @@
|
|
|
138
145
|
"updated_at": "2026-07-27T12:00:00Z"
|
|
139
146
|
}
|
|
140
147
|
}
|
|
141
|
-
}
|
|
148
|
+
},
|
|
149
|
+
"selectedTrigger": "cron"
|
|
142
150
|
},
|
|
143
151
|
{
|
|
144
152
|
"id": "several-repositories",
|
|
@@ -152,7 +160,9 @@
|
|
|
152
160
|
"OpenHands/agent-server-gui",
|
|
153
161
|
"OpenHands/automation"
|
|
154
162
|
],
|
|
155
|
-
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
163
|
+
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
164
|
+
"maintainers": "",
|
|
165
|
+
"triggerReviewer": "all-hands-bot"
|
|
156
166
|
},
|
|
157
167
|
"upload": {
|
|
158
168
|
"request": {
|
|
@@ -166,6 +176,7 @@
|
|
|
166
176
|
"config.json",
|
|
167
177
|
"main.py",
|
|
168
178
|
"github_client.py",
|
|
179
|
+
"maintainer_handoff.py",
|
|
169
180
|
"worker.py"
|
|
170
181
|
]
|
|
171
182
|
},
|
|
@@ -198,7 +209,7 @@
|
|
|
198
209
|
"timeout": 300,
|
|
199
210
|
"template": {
|
|
200
211
|
"id": "github-pr-reviewer",
|
|
201
|
-
"version": "1.
|
|
212
|
+
"version": "1.3.0",
|
|
202
213
|
"config": {
|
|
203
214
|
"repos": [
|
|
204
215
|
"OpenHands/agent-server-gui",
|
|
@@ -206,7 +217,9 @@
|
|
|
206
217
|
],
|
|
207
218
|
"trigger_label": "openhands-review",
|
|
208
219
|
"review_tone": "thorough",
|
|
209
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
220
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
221
|
+
"maintainers": "",
|
|
222
|
+
"trigger_reviewer": "all-hands-bot"
|
|
210
223
|
}
|
|
211
224
|
}
|
|
212
225
|
}
|
|
@@ -236,7 +249,7 @@
|
|
|
236
249
|
"timeout": 300,
|
|
237
250
|
"template": {
|
|
238
251
|
"id": "github-pr-reviewer",
|
|
239
|
-
"version": "1.
|
|
252
|
+
"version": "1.3.0",
|
|
240
253
|
"config": {
|
|
241
254
|
"repos": [
|
|
242
255
|
"OpenHands/agent-server-gui",
|
|
@@ -244,7 +257,9 @@
|
|
|
244
257
|
],
|
|
245
258
|
"trigger_label": "openhands-review",
|
|
246
259
|
"review_tone": "thorough",
|
|
247
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
260
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
261
|
+
"maintainers": "",
|
|
262
|
+
"trigger_reviewer": "all-hands-bot"
|
|
248
263
|
}
|
|
249
264
|
}
|
|
250
265
|
}
|
|
@@ -275,7 +290,7 @@
|
|
|
275
290
|
"preset_metadata": {
|
|
276
291
|
"template": {
|
|
277
292
|
"id": "github-pr-reviewer",
|
|
278
|
-
"version": "1.
|
|
293
|
+
"version": "1.3.0",
|
|
279
294
|
"config": {
|
|
280
295
|
"repos": [
|
|
281
296
|
"OpenHands/agent-server-gui",
|
|
@@ -283,13 +298,16 @@
|
|
|
283
298
|
],
|
|
284
299
|
"trigger_label": "openhands-review",
|
|
285
300
|
"review_tone": "thorough",
|
|
286
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
301
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
302
|
+
"maintainers": "",
|
|
303
|
+
"trigger_reviewer": "all-hands-bot"
|
|
287
304
|
}
|
|
288
305
|
}
|
|
289
306
|
}
|
|
290
307
|
}
|
|
291
308
|
}
|
|
292
|
-
}
|
|
309
|
+
},
|
|
310
|
+
"selectedTrigger": "cron"
|
|
293
311
|
},
|
|
294
312
|
{
|
|
295
313
|
"id": "interval-below-deployment-minimum",
|
|
@@ -302,7 +320,9 @@
|
|
|
302
320
|
"repositories": [
|
|
303
321
|
"OpenHands/agent-server-gui"
|
|
304
322
|
],
|
|
305
|
-
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
323
|
+
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
324
|
+
"maintainers": "",
|
|
325
|
+
"triggerReviewer": "all-hands-bot"
|
|
306
326
|
},
|
|
307
327
|
"preflight": {
|
|
308
328
|
"request": {
|
|
@@ -323,14 +343,16 @@
|
|
|
323
343
|
"timeout": 300,
|
|
324
344
|
"template": {
|
|
325
345
|
"id": "github-pr-reviewer",
|
|
326
|
-
"version": "1.
|
|
346
|
+
"version": "1.3.0",
|
|
327
347
|
"config": {
|
|
328
348
|
"repos": [
|
|
329
349
|
"OpenHands/agent-server-gui"
|
|
330
350
|
],
|
|
331
351
|
"trigger_label": "openhands-review",
|
|
332
352
|
"review_tone": "concise",
|
|
333
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
353
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
354
|
+
"maintainers": "",
|
|
355
|
+
"trigger_reviewer": "all-hands-bot"
|
|
334
356
|
}
|
|
335
357
|
}
|
|
336
358
|
}
|
|
@@ -352,7 +374,8 @@
|
|
|
352
374
|
},
|
|
353
375
|
"expectedFieldErrors": {
|
|
354
376
|
"schedule": "Minimum interval for this deployment is 5 minutes."
|
|
355
|
-
}
|
|
377
|
+
},
|
|
378
|
+
"selectedTrigger": "cron"
|
|
356
379
|
},
|
|
357
380
|
{
|
|
358
381
|
"id": "unfireable-cron-rejected-at-create",
|
|
@@ -365,7 +388,9 @@
|
|
|
365
388
|
"repositories": [
|
|
366
389
|
"OpenHands/agent-server-gui"
|
|
367
390
|
],
|
|
368
|
-
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
391
|
+
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
392
|
+
"maintainers": "",
|
|
393
|
+
"triggerReviewer": "all-hands-bot"
|
|
369
394
|
},
|
|
370
395
|
"upload": {
|
|
371
396
|
"request": {
|
|
@@ -379,6 +404,7 @@
|
|
|
379
404
|
"config.json",
|
|
380
405
|
"main.py",
|
|
381
406
|
"github_client.py",
|
|
407
|
+
"maintainer_handoff.py",
|
|
382
408
|
"worker.py"
|
|
383
409
|
]
|
|
384
410
|
},
|
|
@@ -408,14 +434,16 @@
|
|
|
408
434
|
"timeout": 300,
|
|
409
435
|
"template": {
|
|
410
436
|
"id": "github-pr-reviewer",
|
|
411
|
-
"version": "1.
|
|
437
|
+
"version": "1.3.0",
|
|
412
438
|
"config": {
|
|
413
439
|
"repos": [
|
|
414
440
|
"OpenHands/agent-server-gui"
|
|
415
441
|
],
|
|
416
442
|
"trigger_label": "openhands-review",
|
|
417
443
|
"review_tone": "concise",
|
|
418
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
444
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
445
|
+
"maintainers": "",
|
|
446
|
+
"trigger_reviewer": "all-hands-bot"
|
|
419
447
|
}
|
|
420
448
|
}
|
|
421
449
|
}
|
|
@@ -440,7 +468,8 @@
|
|
|
440
468
|
},
|
|
441
469
|
"expectedFieldErrors": {
|
|
442
470
|
"schedule": "Value error, Cron expression cannot produce any future fire times: 0 0 31 2 *"
|
|
443
|
-
}
|
|
471
|
+
},
|
|
472
|
+
"selectedTrigger": "cron"
|
|
444
473
|
},
|
|
445
474
|
{
|
|
446
475
|
"id": "repos-on-the-raw-create-request-is-rejected",
|
|
@@ -453,7 +482,9 @@
|
|
|
453
482
|
"repositories": [
|
|
454
483
|
"OpenHands/agent-server-gui"
|
|
455
484
|
],
|
|
456
|
-
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
485
|
+
"githubTokenSecret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
486
|
+
"maintainers": "",
|
|
487
|
+
"triggerReviewer": "all-hands-bot"
|
|
457
488
|
},
|
|
458
489
|
"upload": {
|
|
459
490
|
"request": {
|
|
@@ -467,6 +498,7 @@
|
|
|
467
498
|
"config.json",
|
|
468
499
|
"main.py",
|
|
469
500
|
"github_client.py",
|
|
501
|
+
"maintainer_handoff.py",
|
|
470
502
|
"worker.py"
|
|
471
503
|
]
|
|
472
504
|
},
|
|
@@ -496,14 +528,16 @@
|
|
|
496
528
|
"timeout": 300,
|
|
497
529
|
"template": {
|
|
498
530
|
"id": "github-pr-reviewer",
|
|
499
|
-
"version": "1.
|
|
531
|
+
"version": "1.3.0",
|
|
500
532
|
"config": {
|
|
501
533
|
"repos": [
|
|
502
534
|
"OpenHands/agent-server-gui"
|
|
503
535
|
],
|
|
504
536
|
"trigger_label": "openhands-review",
|
|
505
537
|
"review_tone": "concise",
|
|
506
|
-
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|
538
|
+
"github_token_secret": "GITHUB_PERSONAL_ACCESS_TOKEN",
|
|
539
|
+
"maintainers": "",
|
|
540
|
+
"trigger_reviewer": "all-hands-bot"
|
|
507
541
|
}
|
|
508
542
|
},
|
|
509
543
|
"repos": [
|
|
@@ -530,7 +564,67 @@
|
|
|
530
564
|
}
|
|
531
565
|
}
|
|
532
566
|
},
|
|
533
|
-
"matchesSetupPayload": false
|
|
567
|
+
"matchesSetupPayload": false,
|
|
568
|
+
"selectedTrigger": "cron"
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
"id": "reviewer-request-event",
|
|
572
|
+
"description": "A reviewer request selects the event trigger and filters the shared GitHub source to configured repositories, the configured bot request, and that bot's completion review.",
|
|
573
|
+
"selectedTrigger": "event",
|
|
574
|
+
"formValues": {
|
|
575
|
+
"triggerLabel": "openhands-review",
|
|
576
|
+
"triggerReviewer": "all-hands-bot",
|
|
577
|
+
"reviewTone": "concise",
|
|
578
|
+
"on": "*",
|
|
579
|
+
"repositories": [
|
|
580
|
+
"OpenHands/automation"
|
|
581
|
+
],
|
|
582
|
+
"githubTokenSecret": "GITHUB_TOKEN_REVIEW",
|
|
583
|
+
"maintainers": "neubig,malhotra5"
|
|
584
|
+
},
|
|
585
|
+
"preflight": {
|
|
586
|
+
"request": {
|
|
587
|
+
"method": "POST",
|
|
588
|
+
"path": "/v1/validate",
|
|
589
|
+
"body": {
|
|
590
|
+
"automationId": "github-pr-reviewer",
|
|
591
|
+
"endpoint": "/v1",
|
|
592
|
+
"draft": {
|
|
593
|
+
"name": "GitHub code review - OpenHands/automation",
|
|
594
|
+
"trigger": {
|
|
595
|
+
"type": "event",
|
|
596
|
+
"on": "*",
|
|
597
|
+
"source": "github",
|
|
598
|
+
"filter": "contains(['OpenHands/automation'], repository.full_name) && contains(keys(@), 'pull_request') && ((action == 'review_requested' && requested_reviewer.login == 'all-hands-bot') || (action == 'submitted' && contains(keys(@), 'review') && review.user.login == 'all-hands-bot'))"
|
|
599
|
+
},
|
|
600
|
+
"tarball_path": "oh-internal://uploads/00000000-0000-0000-0000-000000000000",
|
|
601
|
+
"entrypoint": "python3 worker.py",
|
|
602
|
+
"timeout": 300,
|
|
603
|
+
"template": {
|
|
604
|
+
"id": "github-pr-reviewer",
|
|
605
|
+
"version": "1.3.0",
|
|
606
|
+
"config": {
|
|
607
|
+
"repos": [
|
|
608
|
+
"OpenHands/automation"
|
|
609
|
+
],
|
|
610
|
+
"trigger_label": "openhands-review",
|
|
611
|
+
"trigger_reviewer": "all-hands-bot",
|
|
612
|
+
"review_tone": "concise",
|
|
613
|
+
"maintainers": "neubig,malhotra5",
|
|
614
|
+
"github_token_secret": "GITHUB_TOKEN_REVIEW"
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
"response": {
|
|
621
|
+
"status": 200,
|
|
622
|
+
"body": {
|
|
623
|
+
"valid": true,
|
|
624
|
+
"errors": []
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
534
628
|
}
|
|
535
629
|
]
|
|
536
630
|
}
|
|
@@ -4,6 +4,7 @@ from uuid import NAMESPACE_URL, UUID, uuid5
|
|
|
4
4
|
|
|
5
5
|
import agent_conversation
|
|
6
6
|
import github_client
|
|
7
|
+
import pytest
|
|
7
8
|
from openhands.sdk.conversation.state import ConversationExecutionStatus
|
|
8
9
|
from openhands.sdk.secret import LookupSecret
|
|
9
10
|
|
|
@@ -130,7 +131,17 @@ def test_known_subject_resumes_once_per_delivery(monkeypatch):
|
|
|
130
131
|
conversation.run.assert_called_once_with(blocking=False)
|
|
131
132
|
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
@pytest.mark.parametrize(
|
|
135
|
+
("status", "disposition", "should_run"),
|
|
136
|
+
[
|
|
137
|
+
(ConversationExecutionStatus.IDLE, "resumed", True),
|
|
138
|
+
(ConversationExecutionStatus.PAUSED, "resumed", True),
|
|
139
|
+
(ConversationExecutionStatus.RUNNING, "in_progress", False),
|
|
140
|
+
],
|
|
141
|
+
)
|
|
142
|
+
def test_same_delivery_resumes_only_inactive_conversation(
|
|
143
|
+
monkeypatch, status, disposition, should_run
|
|
144
|
+
):
|
|
134
145
|
state = {
|
|
135
146
|
_state_key("repo:pr:9"): {
|
|
136
147
|
"subject": "repo:pr:9",
|
|
@@ -147,7 +158,7 @@ def test_same_delivery_resumes_paused_conversation(monkeypatch):
|
|
|
147
158
|
agent_conversation, "RemoteWorkspace", lambda **kwargs: workspace
|
|
148
159
|
)
|
|
149
160
|
conversation = MagicMock()
|
|
150
|
-
conversation.state.execution_status =
|
|
161
|
+
conversation.state.execution_status = status
|
|
151
162
|
monkeypatch.setattr(
|
|
152
163
|
agent_conversation.RemoteConversation,
|
|
153
164
|
"attach",
|
|
@@ -157,9 +168,13 @@ def test_same_delivery_resumes_paused_conversation(monkeypatch):
|
|
|
157
168
|
with _dispatcher(monkeypatch) as dispatcher:
|
|
158
169
|
result = dispatcher.deliver("repo:pr:9", "head-1", "old")
|
|
159
170
|
|
|
160
|
-
assert result["disposition"] ==
|
|
171
|
+
assert result["disposition"] == disposition
|
|
161
172
|
conversation.send_message.assert_not_called()
|
|
162
|
-
conversation.
|
|
173
|
+
conversation.update_secrets.assert_called_once_with(dispatcher._secrets)
|
|
174
|
+
if should_run:
|
|
175
|
+
conversation.run.assert_called_once_with(blocking=False)
|
|
176
|
+
else:
|
|
177
|
+
conversation.run.assert_not_called()
|
|
163
178
|
|
|
164
179
|
|
|
165
180
|
def test_subjects_use_independent_kv_records(monkeypatch):
|
|
@@ -654,6 +654,21 @@ def test_schema_file_is_valid_draft_2020_12() -> None:
|
|
|
654
654
|
Draft202012Validator.check_schema(_SCHEMA)
|
|
655
655
|
|
|
656
656
|
|
|
657
|
+
def test_schema_allows_event_filter_on_script_bundle() -> None:
|
|
658
|
+
entry = deepcopy(_load(CATALOG_DIR / "github-pr-reviewer" / "manifest.json"))
|
|
659
|
+
entry["setup"]["form"]["triggers"]["event"] = {
|
|
660
|
+
"on": {
|
|
661
|
+
"type": "event-type",
|
|
662
|
+
"label": "Event type",
|
|
663
|
+
"help": "GitHub event that starts the bundled script.",
|
|
664
|
+
"required": True,
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
entry["setup"]["filter"] = "repository.full_name == 'owner/repo'"
|
|
668
|
+
|
|
669
|
+
assert list(VALIDATOR.iter_errors(entry)) == []
|
|
670
|
+
|
|
671
|
+
|
|
657
672
|
def test_schema_rejects_content_a_setup_block_must_never_carry() -> None:
|
|
658
673
|
"""The format constraints are the trust boundary, so they are asserted here.
|
|
659
674
|
|
|
@@ -80,8 +80,8 @@ class TestCodeReviewSkillReferencesRisk:
|
|
|
80
80
|
|
|
81
81
|
def test_risk_section_appears_after_dependency_section(self):
|
|
82
82
|
content = get_code_review_skill()
|
|
83
|
-
dep_pos = content.index("
|
|
84
|
-
risk_pos = content.index("
|
|
83
|
+
dep_pos = content.index("## Dependency and workflow updates")
|
|
84
|
+
risk_pos = content.index("## Risk and Safety Evaluation and output")
|
|
85
85
|
assert risk_pos > dep_pos
|
|
86
86
|
|
|
87
87
|
def test_always_include_risk_instruction(self):
|