@openhands/extensions 0.20.0 → 0.21.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.
Files changed (59) hide show
  1. package/.github/workflows/check-extensions.yml +4 -0
  2. package/.github/workflows/pr-artifacts.yml +294 -0
  3. package/.github/workflows/pr-description-check.yml +4 -2
  4. package/.release-please-manifest.json +1 -1
  5. package/AGENTS.md +27 -3
  6. package/README.md +5 -2
  7. package/automations/bundle-index.js +13 -3
  8. package/automations/catalog/github-agents-md-maintainer/manifest.json +2 -1
  9. package/automations/catalog/github-issue-to-pr/manifest.json +2 -1
  10. package/automations/catalog/github-issue-triage/manifest.json +72 -0
  11. package/automations/catalog/github-pr-reviewer/manifest.json +2 -1
  12. package/automations/catalog/gitlab-issue-to-mr/manifest.json +124 -0
  13. package/automations/catalog-index.js +15 -11
  14. package/integrations/catalog/reportportal.json +76 -0
  15. package/integrations/catalog-index.js +6 -4
  16. package/marketplaces/openhands-extensions.json +36 -0
  17. package/package.json +1 -1
  18. package/pyproject.toml +2 -2
  19. package/python/openhands_extensions/_version.py +1 -1
  20. package/skills/github/scripts/github_client.py +204 -0
  21. package/skills/github-agents-md-maintainer/SKILL.md +7 -1
  22. package/skills/github-agents-md-maintainer/scripts/main.py +4 -40
  23. package/skills/github-issue-to-pr/SKILL.md +8 -1
  24. package/skills/github-issue-to-pr/scripts/main.py +3 -40
  25. package/skills/github-issue-triage/.plugin/plugin.json +9 -0
  26. package/skills/github-issue-triage/README.md +9 -0
  27. package/skills/github-issue-triage/SKILL.md +37 -0
  28. package/skills/github-issue-triage/commands/github-issue-triage.md +8 -0
  29. package/skills/github-issue-triage/scripts/worker.py +123 -0
  30. package/skills/github-pr-reviewer/SKILL.md +8 -1
  31. package/skills/github-pr-reviewer/scripts/main.py +3 -41
  32. package/skills/github-repo-monitor/SKILL.md +7 -1
  33. package/skills/github-repo-monitor/scripts/main.py +4 -46
  34. package/skills/gitlab-issue-to-mr/.plugin/plugin.json +19 -0
  35. package/skills/gitlab-issue-to-mr/README.md +92 -0
  36. package/skills/gitlab-issue-to-mr/SKILL.md +408 -0
  37. package/skills/gitlab-issue-to-mr/commands/issue-to-mr-setup.md +8 -0
  38. package/skills/gitlab-issue-to-mr/references/state-schema.md +140 -0
  39. package/skills/gitlab-issue-to-mr/scripts/main.py +1448 -0
  40. package/skills/index.js +43 -6
  41. package/skills/openhands-automation/README.md +1 -1
  42. package/skills/openhands-automation/SKILL.md +18 -8
  43. package/skills/openhands-enterprise-troubleshooting/.plugin/plugin.json +20 -0
  44. package/skills/openhands-enterprise-troubleshooting/README.md +79 -0
  45. package/skills/openhands-enterprise-troubleshooting/SKILL.md +339 -0
  46. package/skills/openhands-enterprise-troubleshooting/references/diagnostics.md +698 -0
  47. package/skills/openhands-enterprise-troubleshooting/references/support-bundle-analysis.md +570 -0
  48. package/skills/openhands-enterprise-troubleshooting/scripts/bundle_triage.py +532 -0
  49. package/skills/openhands-sdk/SKILL.md +2 -0
  50. package/tests/github_automation_helpers.py +25 -0
  51. package/tests/test_github_automation_foundation.py +73 -0
  52. package/tests/test_github_skill_installation.py +63 -0
  53. package/tests/test_github_triage_delivery.py +53 -0
  54. package/tests/test_gitlab_issue_to_mr.py +823 -0
  55. package/.pr/custom-automation-event-trigger.png +0 -0
  56. package/.pr/custom-automation-plugin-fields.png +0 -0
  57. package/.pr/custom-automation-prompt-review.png +0 -0
  58. package/.pr/custom-automation-prompt-scheduled.png +0 -0
  59. package/.pr/custom-automation-upload-fields.png +0 -0
@@ -0,0 +1,63 @@
1
+ """Verify shared support is included in independently installed skills."""
2
+
3
+ import json
4
+ import subprocess
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+ from openhands.sdk.skills import install_skill
10
+
11
+ ROOT = Path(__file__).resolve().parents[1]
12
+
13
+
14
+ def test_installed_triage_skill_contains_its_bundle(tmp_path):
15
+ name = "github-issue-triage"
16
+ install_skill(source=str(ROOT / "skills" / name), installed_dir=tmp_path)
17
+ scripts = tmp_path / name / "scripts"
18
+ manifest = json.loads(
19
+ (ROOT / f"automations/catalog/{name}/manifest.json").read_text()
20
+ )
21
+
22
+ for filename, source in manifest["setup"]["bundle"]["files"].items():
23
+ installed = scripts / filename
24
+ assert installed.is_file() and not installed.is_symlink()
25
+ assert installed.read_bytes() == (ROOT / source).read_bytes()
26
+
27
+ result = subprocess.run(
28
+ [sys.executable, "-c", "import worker"],
29
+ cwd=scripts,
30
+ text=True,
31
+ capture_output=True,
32
+ check=False,
33
+ )
34
+ assert result.returncode == 0, result.stderr
35
+
36
+
37
+ @pytest.mark.parametrize(
38
+ "name",
39
+ [
40
+ "github-repo-monitor",
41
+ "github-agents-md-maintainer",
42
+ "github-issue-to-pr",
43
+ "github-pr-reviewer",
44
+ ],
45
+ )
46
+ def test_installed_github_skill_contains_shared_client(tmp_path, name):
47
+ install_skill(source=str(ROOT / "skills" / name), installed_dir=tmp_path)
48
+ scripts = tmp_path / name / "scripts"
49
+ helper = scripts / "github_client.py"
50
+
51
+ assert helper.is_file() and not helper.is_symlink()
52
+ assert (
53
+ helper.read_bytes()
54
+ == (ROOT / "skills/github/scripts/github_client.py").read_bytes()
55
+ )
56
+ result = subprocess.run(
57
+ [sys.executable, "-c", "import main"],
58
+ cwd=scripts,
59
+ text=True,
60
+ capture_output=True,
61
+ check=False,
62
+ )
63
+ assert result.returncode == 0, result.stderr
@@ -0,0 +1,53 @@
1
+ """Contract tests for independent triage delivery."""
2
+
3
+ import json
4
+ from unittest.mock import Mock
5
+
6
+ import pytest
7
+ from github_automation_helpers import worker
8
+
9
+
10
+ @pytest.mark.parametrize(
11
+ "ready,criteria",
12
+ [(True, ["One observable result"]), (False, ["Clarify account ownership"])],
13
+ )
14
+ def test_triage_preserves_labels_and_only_readies_clear_work(
15
+ tmp_path, monkeypatch, ready, criteria
16
+ ):
17
+ cls = worker("github-issue-triage", tmp_path, monkeypatch).IssueTriage
18
+ run = object.__new__(cls)
19
+ issue = {
20
+ "number": 1,
21
+ "title": "A small feature",
22
+ "body": "",
23
+ "labels": [{"name": "enhancement"}],
24
+ }
25
+ run.open_issues = lambda: [issue]
26
+ run.gh_pages = lambda path: []
27
+ run.dependencies_complete = lambda issue: True
28
+ result = {
29
+ "ready": ready,
30
+ "priority": "normal",
31
+ "acceptance_criteria": criteria,
32
+ "rationale": "Small independent change",
33
+ }
34
+ run.evidence = tmp_path
35
+ run.conversation = Mock()
36
+ run.conversation.run.side_effect = lambda **kwargs: (
37
+ tmp_path / "triage.json"
38
+ ).write_text(json.dumps(result))
39
+ calls = []
40
+ run.gh = lambda *args: calls.append(args)
41
+ run.comment = lambda *args: calls.append(("comment", *args))
42
+
43
+ run.run()
44
+
45
+ updates = [call for call in calls if call[0] == "PATCH"]
46
+ assert bool(updates) is ready
47
+ if ready:
48
+ assert set(updates[0][2]["labels"]) == {
49
+ "enhancement",
50
+ "priority:normal",
51
+ "ready-for-dev",
52
+ }
53
+ assert criteria[0] in next(call[2] for call in calls if call[0] == "comment")