@openhands/extensions 0.20.0 → 0.22.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/.claude-plugin/marketplace.json +881 -0
- package/.codex-plugin/marketplace.json +881 -0
- package/.github/workflows/check-extensions.yml +4 -0
- package/.github/workflows/npm-publish.yml +9 -3
- package/.github/workflows/pr-artifacts.yml +294 -0
- package/.github/workflows/pr-description-check.yml +4 -2
- package/.plugin/marketplace.json +881 -0
- package/.release-please-manifest.json +1 -1
- package/AGENTS.md +27 -3
- package/README.md +6 -2
- package/automations/bundle-index.js +22 -3
- package/automations/catalog/github-agents-md-maintainer/manifest.json +2 -1
- package/automations/catalog/github-delivery-watchdog/manifest.json +79 -0
- package/automations/catalog/github-issue-to-pr/manifest.json +24 -15
- package/automations/catalog/github-issue-triage/manifest.json +73 -0
- package/automations/catalog/github-pr-reviewer/manifest.json +23 -15
- package/automations/catalog/gitlab-issue-to-mr/manifest.json +124 -0
- package/automations/catalog-index.js +17 -11
- package/integrations/catalog/reportportal.json +76 -0
- package/integrations/catalog-index.js +6 -4
- package/marketplaces/openhands-extensions.json +42 -0
- package/package.json +1 -1
- package/plugins/city-weather/.claude-plugin/plugin.json +13 -0
- package/plugins/city-weather/.codex-plugin/plugin.json +13 -0
- package/plugins/cobol-modernization/.claude-plugin/plugin.json +19 -0
- package/plugins/cobol-modernization/.codex-plugin/plugin.json +19 -0
- package/plugins/issue-duplicate-checker/.claude-plugin/plugin.json +13 -0
- package/plugins/issue-duplicate-checker/.codex-plugin/plugin.json +13 -0
- package/plugins/magic-test/.claude-plugin/plugin.json +13 -0
- package/plugins/magic-test/.codex-plugin/plugin.json +13 -0
- package/plugins/migration-scoring/.claude-plugin/plugin.json +19 -0
- package/plugins/migration-scoring/.codex-plugin/plugin.json +19 -0
- package/plugins/onboarding/.claude-plugin/plugin.json +20 -0
- package/plugins/onboarding/.codex-plugin/plugin.json +20 -0
- package/plugins/onboarding/skills/agent-readiness-report/references/criteria.md +144 -0
- package/plugins/onboarding/skills/improve-agent-readiness/references/criteria.md +144 -0
- package/plugins/openhands/.claude-plugin/plugin.json +13 -0
- package/plugins/openhands/.codex-plugin/plugin.json +13 -0
- package/plugins/openhands/skills/openhands-api/.claude-plugin/plugin.json +22 -0
- package/plugins/openhands/skills/openhands-api/.codex-plugin/plugin.json +22 -0
- package/plugins/openhands/skills/openhands-api/.plugin/plugin.json +22 -0
- package/plugins/openhands/skills/openhands-api/README.md +52 -0
- package/plugins/openhands/skills/openhands-api/SKILL.md +469 -0
- package/plugins/openhands/skills/openhands-api/references/README.md +33 -0
- package/plugins/openhands/skills/openhands-api/references/TROUBLESHOOTING.md +81 -0
- package/plugins/openhands/skills/openhands-api/references/example_prompt.md +12 -0
- package/plugins/openhands/skills/openhands-api/references/windows.md +44 -0
- package/plugins/openhands/skills/openhands-api/scripts/openhands_api.py +606 -0
- package/plugins/openhands/skills/openhands-api/scripts/openhands_api.ts +252 -0
- package/plugins/openhands/skills/openhands-automation/.claude-plugin/plugin.json +19 -0
- package/plugins/openhands/skills/openhands-automation/.codex-plugin/plugin.json +19 -0
- package/plugins/openhands/skills/openhands-automation/.plugin/plugin.json +19 -0
- package/plugins/openhands/skills/openhands-automation/README.md +89 -0
- package/plugins/openhands/skills/openhands-automation/SKILL.md +899 -0
- package/plugins/openhands/skills/openhands-automation/commands/automation-create.md +8 -0
- package/plugins/openhands/skills/openhands-automation/references/ab-testing.md +185 -0
- package/plugins/openhands/skills/openhands-automation/references/custom-automation.md +832 -0
- package/plugins/openhands/skills/openhands-automation/references/security.md +84 -0
- package/plugins/openhands/skills/openhands-automation/references/windows.md +57 -0
- package/plugins/openhands/skills/openhands-sdk/.claude-plugin/plugin.json +20 -0
- package/plugins/openhands/skills/openhands-sdk/.codex-plugin/plugin.json +20 -0
- package/plugins/openhands/skills/openhands-sdk/.plugin/plugin.json +20 -0
- package/plugins/openhands/skills/openhands-sdk/README.md +22 -0
- package/plugins/openhands/skills/openhands-sdk/SKILL.md +245 -0
- package/plugins/openhands/skills/openhands-sdk/commands/sdk.md +8 -0
- package/plugins/pr-review/.claude-plugin/plugin.json +13 -0
- package/plugins/pr-review/.codex-plugin/plugin.json +13 -0
- package/plugins/pr-review/skills/code-review/.claude-plugin/plugin.json +19 -0
- package/plugins/pr-review/skills/code-review/.codex-plugin/plugin.json +19 -0
- package/plugins/pr-review/skills/code-review/.plugin/plugin.json +19 -0
- package/plugins/pr-review/skills/code-review/README.md +18 -0
- package/plugins/pr-review/skills/code-review/SKILL.md +209 -0
- package/plugins/pr-review/skills/code-review/commands/codereview-roasted.md +8 -0
- package/plugins/pr-review/skills/code-review/commands/codereview.md +8 -0
- package/plugins/pr-review/skills/code-review/references/risk-evaluation.md +41 -0
- package/plugins/pr-review/skills/code-review/references/supply-chain-security.md +31 -0
- package/plugins/pr-review/skills/github-pr-review/.claude-plugin/plugin.json +18 -0
- package/plugins/pr-review/skills/github-pr-review/.codex-plugin/plugin.json +18 -0
- package/plugins/pr-review/skills/github-pr-review/.plugin/plugin.json +18 -0
- package/plugins/pr-review/skills/github-pr-review/README.md +145 -0
- package/plugins/pr-review/skills/github-pr-review/SKILL.md +187 -0
- package/plugins/pr-review/skills/github-pr-review/commands/github-pr-review.md +8 -0
- package/plugins/pr-review/skills/github-pr-review/references/windows.md +47 -0
- package/plugins/qa-changes/.claude-plugin/plugin.json +11 -0
- package/plugins/qa-changes/.codex-plugin/plugin.json +11 -0
- package/plugins/qa-changes/skills/github-pr-review/.claude-plugin/plugin.json +18 -0
- package/plugins/qa-changes/skills/github-pr-review/.codex-plugin/plugin.json +18 -0
- package/plugins/qa-changes/skills/github-pr-review/.plugin/plugin.json +18 -0
- package/plugins/qa-changes/skills/github-pr-review/README.md +145 -0
- package/plugins/qa-changes/skills/github-pr-review/SKILL.md +187 -0
- package/plugins/qa-changes/skills/github-pr-review/commands/github-pr-review.md +8 -0
- package/plugins/qa-changes/skills/github-pr-review/references/windows.md +47 -0
- package/plugins/qa-changes/skills/qa-changes/README.md +18 -0
- package/plugins/qa-changes/skills/qa-changes/SKILL.md +229 -0
- package/plugins/qa-changes/skills/qa-changes/commands/qa-changes.md +8 -0
- package/plugins/release-notes/.claude-plugin/plugin.json +19 -0
- package/plugins/release-notes/.codex-plugin/plugin.json +19 -0
- package/plugins/release-notes/skills/release-notes/README.md +24 -0
- package/plugins/release-notes/skills/release-notes/SKILL.md +19 -0
- package/plugins/release-notes/skills/release-notes/commands/release-notes.md +8 -0
- package/plugins/vulnerability-remediation/.claude-plugin/plugin.json +19 -0
- package/plugins/vulnerability-remediation/.codex-plugin/plugin.json +19 -0
- package/plugins/vulnerability-remediation/skills/github/.claude-plugin/plugin.json +19 -0
- package/plugins/vulnerability-remediation/skills/github/.codex-plugin/plugin.json +19 -0
- package/plugins/vulnerability-remediation/skills/github/.plugin/plugin.json +19 -0
- package/plugins/vulnerability-remediation/skills/github/README.md +42 -0
- package/plugins/vulnerability-remediation/skills/github/SKILL.md +107 -0
- package/plugins/vulnerability-remediation/skills/github/references/windows.md +48 -0
- package/plugins/vulnerability-remediation/skills/github/scripts/agent_conversation.py +143 -0
- package/plugins/vulnerability-remediation/skills/github/scripts/github_client.py +230 -0
- package/plugins/vulnerability-remediation/skills/security/.claude-plugin/plugin.json +18 -0
- package/plugins/vulnerability-remediation/skills/security/.codex-plugin/plugin.json +18 -0
- package/plugins/vulnerability-remediation/skills/security/.plugin/plugin.json +18 -0
- package/plugins/vulnerability-remediation/skills/security/README.md +38 -0
- package/plugins/vulnerability-remediation/skills/security/SKILL.md +33 -0
- package/pyproject.toml +2 -2
- package/python/openhands_extensions/_version.py +1 -1
- package/skills/add-javadoc/.claude-plugin/plugin.json +18 -0
- package/skills/add-javadoc/.codex-plugin/plugin.json +18 -0
- package/skills/add-skill/.claude-plugin/plugin.json +18 -0
- package/skills/add-skill/.codex-plugin/plugin.json +18 -0
- package/skills/agent-canvas-environment/.claude-plugin/plugin.json +19 -0
- package/skills/agent-canvas-environment/.codex-plugin/plugin.json +19 -0
- package/skills/agent-creator/.claude-plugin/plugin.json +20 -0
- package/skills/agent-creator/.codex-plugin/plugin.json +20 -0
- package/skills/agent-memory/.claude-plugin/plugin.json +18 -0
- package/skills/agent-memory/.codex-plugin/plugin.json +18 -0
- package/skills/agent-sdk-builder/.claude-plugin/plugin.json +18 -0
- package/skills/agent-sdk-builder/.codex-plugin/plugin.json +18 -0
- package/skills/azure-devops/.claude-plugin/plugin.json +18 -0
- package/skills/azure-devops/.codex-plugin/plugin.json +18 -0
- package/skills/bitbucket/.claude-plugin/plugin.json +17 -0
- package/skills/bitbucket/.codex-plugin/plugin.json +17 -0
- package/skills/bitbucket-cloud/.claude-plugin/plugin.json +18 -0
- package/skills/bitbucket-cloud/.codex-plugin/plugin.json +18 -0
- package/skills/bitbucket-data-center/.claude-plugin/plugin.json +19 -0
- package/skills/bitbucket-data-center/.codex-plugin/plugin.json +19 -0
- package/skills/code-review/.claude-plugin/plugin.json +19 -0
- package/skills/code-review/.codex-plugin/plugin.json +19 -0
- package/skills/code-simplifier/.claude-plugin/plugin.json +21 -0
- package/skills/code-simplifier/.codex-plugin/plugin.json +21 -0
- package/skills/datadog/.claude-plugin/plugin.json +19 -0
- package/skills/datadog/.codex-plugin/plugin.json +19 -0
- package/skills/deno/.claude-plugin/plugin.json +18 -0
- package/skills/deno/.codex-plugin/plugin.json +18 -0
- package/skills/discord/.claude-plugin/plugin.json +18 -0
- package/skills/discord/.codex-plugin/plugin.json +18 -0
- package/skills/docker/.claude-plugin/plugin.json +17 -0
- package/skills/docker/.codex-plugin/plugin.json +17 -0
- package/skills/evidence-based-citations/.claude-plugin/plugin.json +20 -0
- package/skills/evidence-based-citations/.codex-plugin/plugin.json +20 -0
- package/skills/flarglebargle/.claude-plugin/plugin.json +16 -0
- package/skills/flarglebargle/.codex-plugin/plugin.json +16 -0
- package/skills/frontend-design/.claude-plugin/plugin.json +21 -0
- package/skills/frontend-design/.codex-plugin/plugin.json +21 -0
- package/skills/github/.claude-plugin/plugin.json +19 -0
- package/skills/github/.codex-plugin/plugin.json +19 -0
- package/skills/github/scripts/agent_conversation.py +143 -0
- package/skills/github/scripts/github_client.py +230 -0
- package/skills/github-actions/.claude-plugin/plugin.json +19 -0
- package/skills/github-actions/.codex-plugin/plugin.json +19 -0
- package/skills/github-agents-md-maintainer/.claude-plugin/plugin.json +19 -0
- package/skills/github-agents-md-maintainer/.codex-plugin/plugin.json +19 -0
- package/skills/github-agents-md-maintainer/SKILL.md +7 -1
- package/skills/github-agents-md-maintainer/scripts/github_client.py +230 -0
- package/skills/github-agents-md-maintainer/scripts/main.py +4 -40
- package/skills/github-delivery-watchdog/.claude-plugin/plugin.json +9 -0
- package/skills/github-delivery-watchdog/.codex-plugin/plugin.json +9 -0
- package/skills/github-delivery-watchdog/.plugin/plugin.json +9 -0
- package/skills/github-delivery-watchdog/README.md +10 -0
- package/skills/github-delivery-watchdog/SKILL.md +35 -0
- package/skills/github-delivery-watchdog/commands/github-delivery-watchdog.md +8 -0
- package/skills/github-delivery-watchdog/scripts/github_client.py +230 -0
- package/skills/github-delivery-watchdog/scripts/worker.py +96 -0
- package/skills/github-issue-to-pr/.claude-plugin/plugin.json +19 -0
- package/skills/github-issue-to-pr/.codex-plugin/plugin.json +19 -0
- package/skills/github-issue-to-pr/SKILL.md +15 -1
- package/skills/github-issue-to-pr/scripts/agent_conversation.py +143 -0
- package/skills/github-issue-to-pr/scripts/github_client.py +230 -0
- package/skills/github-issue-to-pr/scripts/main.py +19 -50
- package/skills/github-issue-to-pr/scripts/worker.py +172 -0
- package/skills/github-issue-triage/.claude-plugin/plugin.json +9 -0
- package/skills/github-issue-triage/.codex-plugin/plugin.json +9 -0
- package/skills/github-issue-triage/.plugin/plugin.json +9 -0
- package/skills/github-issue-triage/README.md +9 -0
- package/skills/github-issue-triage/SKILL.md +34 -0
- package/skills/github-issue-triage/commands/github-issue-triage.md +8 -0
- package/skills/github-issue-triage/scripts/agent_conversation.py +143 -0
- package/skills/github-issue-triage/scripts/github_client.py +230 -0
- package/skills/github-issue-triage/scripts/worker.py +106 -0
- package/skills/github-pr-review/.claude-plugin/plugin.json +18 -0
- package/skills/github-pr-review/.codex-plugin/plugin.json +18 -0
- package/skills/github-pr-reviewer/.claude-plugin/plugin.json +20 -0
- package/skills/github-pr-reviewer/.codex-plugin/plugin.json +20 -0
- package/skills/github-pr-reviewer/SKILL.md +15 -1
- package/skills/github-pr-reviewer/scripts/agent_conversation.py +143 -0
- package/skills/github-pr-reviewer/scripts/github_client.py +230 -0
- package/skills/github-pr-reviewer/scripts/main.py +23 -49
- package/skills/github-pr-reviewer/scripts/worker.py +94 -0
- package/skills/github-repo-monitor/.claude-plugin/plugin.json +22 -0
- package/skills/github-repo-monitor/.codex-plugin/plugin.json +22 -0
- package/skills/github-repo-monitor/SKILL.md +7 -1
- package/skills/github-repo-monitor/scripts/github_client.py +230 -0
- package/skills/github-repo-monitor/scripts/main.py +4 -46
- package/skills/gitlab/.claude-plugin/plugin.json +17 -0
- package/skills/gitlab/.codex-plugin/plugin.json +17 -0
- package/skills/gitlab-issue-to-mr/.claude-plugin/plugin.json +19 -0
- package/skills/gitlab-issue-to-mr/.codex-plugin/plugin.json +19 -0
- package/skills/gitlab-issue-to-mr/.plugin/plugin.json +19 -0
- package/skills/gitlab-issue-to-mr/README.md +92 -0
- package/skills/gitlab-issue-to-mr/SKILL.md +408 -0
- package/skills/gitlab-issue-to-mr/commands/issue-to-mr-setup.md +8 -0
- package/skills/gitlab-issue-to-mr/references/state-schema.md +140 -0
- package/skills/gitlab-issue-to-mr/scripts/main.py +1448 -0
- package/skills/incident-retrospective/.claude-plugin/plugin.json +21 -0
- package/skills/incident-retrospective/.codex-plugin/plugin.json +21 -0
- package/skills/index.js +52 -6
- package/skills/iterate/.claude-plugin/plugin.json +13 -0
- package/skills/iterate/.codex-plugin/plugin.json +13 -0
- package/skills/jira-issue-to-pr/.claude-plugin/plugin.json +19 -0
- package/skills/jira-issue-to-pr/.codex-plugin/plugin.json +19 -0
- package/skills/jupyter/.claude-plugin/plugin.json +18 -0
- package/skills/jupyter/.codex-plugin/plugin.json +18 -0
- package/skills/kubernetes/.claude-plugin/plugin.json +18 -0
- package/skills/kubernetes/.codex-plugin/plugin.json +18 -0
- package/skills/learn-from-code-review/.claude-plugin/plugin.json +19 -0
- package/skills/learn-from-code-review/.codex-plugin/plugin.json +19 -0
- package/skills/linear/.claude-plugin/plugin.json +19 -0
- package/skills/linear/.codex-plugin/plugin.json +19 -0
- package/skills/linear-triage/.claude-plugin/plugin.json +21 -0
- package/skills/linear-triage/.codex-plugin/plugin.json +21 -0
- package/skills/news-digest/.claude-plugin/plugin.json +19 -0
- package/skills/news-digest/.codex-plugin/plugin.json +19 -0
- package/skills/notion/.claude-plugin/plugin.json +17 -0
- package/skills/notion/.codex-plugin/plugin.json +17 -0
- package/skills/npm/.claude-plugin/plugin.json +17 -0
- package/skills/npm/.codex-plugin/plugin.json +17 -0
- package/skills/openhands-api/.claude-plugin/plugin.json +22 -0
- package/skills/openhands-api/.codex-plugin/plugin.json +22 -0
- package/skills/openhands-automation/.claude-plugin/plugin.json +19 -0
- package/skills/openhands-automation/.codex-plugin/plugin.json +19 -0
- package/skills/openhands-automation/README.md +1 -1
- package/skills/openhands-automation/SKILL.md +18 -8
- package/skills/openhands-enterprise-troubleshooting/.claude-plugin/plugin.json +20 -0
- package/skills/openhands-enterprise-troubleshooting/.codex-plugin/plugin.json +20 -0
- package/skills/openhands-enterprise-troubleshooting/.plugin/plugin.json +20 -0
- package/skills/openhands-enterprise-troubleshooting/README.md +79 -0
- package/skills/openhands-enterprise-troubleshooting/SKILL.md +339 -0
- package/skills/openhands-enterprise-troubleshooting/references/diagnostics.md +698 -0
- package/skills/openhands-enterprise-troubleshooting/references/support-bundle-analysis.md +570 -0
- package/skills/openhands-enterprise-troubleshooting/scripts/bundle_triage.py +532 -0
- package/skills/openhands-sdk/.claude-plugin/plugin.json +20 -0
- package/skills/openhands-sdk/.codex-plugin/plugin.json +20 -0
- package/skills/openhands-sdk/SKILL.md +2 -0
- package/skills/pdflatex/.claude-plugin/plugin.json +18 -0
- package/skills/pdflatex/.codex-plugin/plugin.json +18 -0
- package/skills/plain-english-content/.claude-plugin/plugin.json +15 -0
- package/skills/plain-english-content/.codex-plugin/plugin.json +15 -0
- package/skills/prd/.claude-plugin/plugin.json +19 -0
- package/skills/prd/.codex-plugin/plugin.json +19 -0
- package/skills/research-brief/.claude-plugin/plugin.json +20 -0
- package/skills/research-brief/.codex-plugin/plugin.json +20 -0
- package/skills/security/.claude-plugin/plugin.json +18 -0
- package/skills/security/.codex-plugin/plugin.json +18 -0
- package/skills/skill-creator/.claude-plugin/plugin.json +17 -0
- package/skills/skill-creator/.codex-plugin/plugin.json +17 -0
- package/skills/slack-channel-monitor/.claude-plugin/plugin.json +21 -0
- package/skills/slack-channel-monitor/.codex-plugin/plugin.json +21 -0
- package/skills/slack-standup-digest/.claude-plugin/plugin.json +21 -0
- package/skills/slack-standup-digest/.codex-plugin/plugin.json +21 -0
- package/skills/spark-version-upgrade/.claude-plugin/plugin.json +20 -0
- package/skills/spark-version-upgrade/.codex-plugin/plugin.json +20 -0
- package/skills/ssh/.claude-plugin/plugin.json +18 -0
- package/skills/ssh/.codex-plugin/plugin.json +18 -0
- package/skills/swift-linux/.claude-plugin/plugin.json +17 -0
- package/skills/swift-linux/.codex-plugin/plugin.json +17 -0
- package/skills/technical-writing/.claude-plugin/plugin.json +15 -0
- package/skills/technical-writing/.codex-plugin/plugin.json +15 -0
- package/skills/theme-factory/.claude-plugin/plugin.json +19 -0
- package/skills/theme-factory/.codex-plugin/plugin.json +19 -0
- package/skills/ticket-to-code-change/.claude-plugin/plugin.json +21 -0
- package/skills/ticket-to-code-change/.codex-plugin/plugin.json +21 -0
- package/skills/upstream-fork-sync/.claude-plugin/plugin.json +21 -0
- package/skills/upstream-fork-sync/.codex-plugin/plugin.json +21 -0
- package/skills/uv/.claude-plugin/plugin.json +18 -0
- package/skills/uv/.codex-plugin/plugin.json +18 -0
- package/skills/vercel/.claude-plugin/plugin.json +18 -0
- package/skills/vercel/.codex-plugin/plugin.json +18 -0
- package/tests/fixtures/automations/capabilities.json +6 -3
- package/tests/fixtures/automations/github-pr-reviewer.json +64 -43
- package/tests/github_automation_helpers.py +31 -0
- package/tests/test_agent_conversation_dispatch.py +180 -0
- package/tests/test_automation_setup.py +3 -3
- package/tests/test_github_automation_foundation.py +73 -0
- package/tests/test_github_developer_delivery.py +150 -0
- package/tests/test_github_reviewer_delivery.py +110 -0
- package/tests/test_github_skill_installation.py +63 -0
- package/tests/test_github_triage_delivery.py +90 -0
- package/tests/test_github_watchdog_delivery.py +233 -0
- package/tests/test_gitlab_issue_to_mr.py +823 -0
- package/.pr/custom-automation-event-trigger.png +0 -0
- package/.pr/custom-automation-plugin-fields.png +0 -0
- package/.pr/custom-automation-prompt-review.png +0 -0
- package/.pr/custom-automation-prompt-scheduled.png +0 -0
- package/.pr/custom-automation-upload-fields.png +0 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/*
|
|
2
|
+
OpenHands Cloud API (V1) minimal client.
|
|
3
|
+
|
|
4
|
+
Audience: AI agents.
|
|
5
|
+
|
|
6
|
+
App server (Cloud):
|
|
7
|
+
- Base: https://app.all-hands.dev
|
|
8
|
+
- Prefix: /api/v1
|
|
9
|
+
- Auth: Authorization: Bearer <OPENHANDS_CLOUD_API_KEY>
|
|
10
|
+
|
|
11
|
+
Agent server (sandbox runtime):
|
|
12
|
+
- Base: {agent_server_url}/api
|
|
13
|
+
- Auth: X-Session-API-Key: <session_api_key>
|
|
14
|
+
|
|
15
|
+
This is intentionally small and keeps responses mostly untyped (unknown/record)
|
|
16
|
+
so it is easy to adapt.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export type OpenHandsOptions = {
|
|
20
|
+
apiKey: string;
|
|
21
|
+
baseUrl?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const AGENT_EVENTS_SEARCH_MAX_LIMIT = 100;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export class OpenHandsAPI {
|
|
28
|
+
private readonly apiKey: string;
|
|
29
|
+
private readonly baseUrl: string;
|
|
30
|
+
|
|
31
|
+
constructor(opts: OpenHandsOptions) {
|
|
32
|
+
if (!opts.apiKey) throw new Error("Missing apiKey");
|
|
33
|
+
this.apiKey = opts.apiKey;
|
|
34
|
+
this.baseUrl = (opts.baseUrl ?? "https://app.all-hands.dev").replace(/\/$/, "");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private get apiV1Url(): string {
|
|
38
|
+
return `${this.baseUrl}/api/v1`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private async baseRequest<T>(
|
|
42
|
+
url: string,
|
|
43
|
+
init: RequestInit | undefined,
|
|
44
|
+
headers: Record<string, string>,
|
|
45
|
+
parseAs: "json" | "blob" = "json",
|
|
46
|
+
): Promise<T> {
|
|
47
|
+
const res = await fetch(url, {
|
|
48
|
+
...init,
|
|
49
|
+
headers: {
|
|
50
|
+
...headers,
|
|
51
|
+
...(init?.headers ?? {}),
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
const text = await res.text().catch(() => "");
|
|
57
|
+
throw new Error(`OpenHands API error ${res.status} ${res.statusText}: ${text}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (parseAs === "blob") return (await res.blob()) as unknown as T;
|
|
61
|
+
return (await res.json()) as T;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private async request<T>(
|
|
65
|
+
url: string,
|
|
66
|
+
init?: RequestInit,
|
|
67
|
+
parseAs: "json" | "blob" = "json",
|
|
68
|
+
): Promise<T> {
|
|
69
|
+
return await this.baseRequest(
|
|
70
|
+
url,
|
|
71
|
+
init,
|
|
72
|
+
{ Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" },
|
|
73
|
+
parseAs,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// -----------------------------
|
|
78
|
+
// App server endpoints
|
|
79
|
+
// -----------------------------
|
|
80
|
+
|
|
81
|
+
async usersMe(): Promise<Record<string, unknown>> {
|
|
82
|
+
return await this.request(`${this.apiV1Url}/users/me`, { method: "GET" });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async appConversationsSearch(limit = 20): Promise<Record<string, unknown>> {
|
|
86
|
+
const safeLimit = Number.isFinite(limit) ? Math.trunc(limit) : 1;
|
|
87
|
+
const params = new URLSearchParams({ limit: String(Math.max(1, safeLimit)) });
|
|
88
|
+
return await this.request(`${this.apiV1Url}/app-conversations/search?${params.toString()}`, {
|
|
89
|
+
method: "GET",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async appConversationsGetBatch(ids: string[]): Promise<Array<Record<string, unknown>>> {
|
|
94
|
+
if (ids.length === 0) return [];
|
|
95
|
+
const params = new URLSearchParams();
|
|
96
|
+
for (const id of ids) params.append("ids", id);
|
|
97
|
+
return await this.request(`${this.apiV1Url}/app-conversations?${params.toString()}`, {
|
|
98
|
+
method: "GET",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async conversationEventsCount(appConversationId: string): Promise<number> {
|
|
103
|
+
const res = await this.request<number>(
|
|
104
|
+
`${this.apiV1Url}/conversation/${encodeURIComponent(appConversationId)}/events/count`,
|
|
105
|
+
{ method: "GET" },
|
|
106
|
+
);
|
|
107
|
+
return Number(res);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async appConversationDownloadZip(appConversationId: string): Promise<Blob> {
|
|
111
|
+
const url = `${this.apiV1Url}/app-conversations/${encodeURIComponent(appConversationId)}/download`;
|
|
112
|
+
return await this.request<Blob>(url, { method: "GET" }, "blob");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async appConversationStart(req: {
|
|
116
|
+
initialMessage: string;
|
|
117
|
+
selectedRepository?: string;
|
|
118
|
+
selectedBranch?: string;
|
|
119
|
+
title?: string;
|
|
120
|
+
run?: boolean;
|
|
121
|
+
}): Promise<Record<string, unknown>> {
|
|
122
|
+
// NOTE: In many deployments this returns a *start-task* object.
|
|
123
|
+
// `id` is usually the start_task_id; use `app_conversation_id` (if present)
|
|
124
|
+
// for `/download` and `/conversation/.../events/...` endpoints.
|
|
125
|
+
// If `app_conversation_id` is missing, fetch it via:
|
|
126
|
+
// GET /api/v1/app-conversations/start-tasks?ids=<start_task_id>
|
|
127
|
+
|
|
128
|
+
const payload: Record<string, unknown> = {
|
|
129
|
+
initial_message: {
|
|
130
|
+
role: "user",
|
|
131
|
+
// V1 expects `content` as an array of parts, even for a single text message.
|
|
132
|
+
content: [{ type: "text", text: req.initialMessage }],
|
|
133
|
+
run: req.run ?? true,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
if (req.selectedRepository) payload.selected_repository = req.selectedRepository;
|
|
137
|
+
if (req.selectedBranch) payload.selected_branch = req.selectedBranch;
|
|
138
|
+
if (req.title) payload.title = req.title;
|
|
139
|
+
|
|
140
|
+
return await this.request(`${this.apiV1Url}/app-conversations`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
body: JSON.stringify(payload),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async appConversationsStartTasksGetBatch(ids: string[]): Promise<Array<Record<string, unknown>>> {
|
|
147
|
+
if (ids.length === 0) return [];
|
|
148
|
+
const params = new URLSearchParams();
|
|
149
|
+
for (const id of ids) params.append("ids", id);
|
|
150
|
+
return await this.request(`${this.apiV1Url}/app-conversations/start-tasks?${params.toString()}`, {
|
|
151
|
+
method: "GET",
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// -----------------------------
|
|
156
|
+
// Agent server endpoints
|
|
157
|
+
// -----------------------------
|
|
158
|
+
|
|
159
|
+
private async agentRequest<T>(
|
|
160
|
+
agentServerUrl: string,
|
|
161
|
+
sessionApiKey: string,
|
|
162
|
+
path: string,
|
|
163
|
+
init?: RequestInit,
|
|
164
|
+
): Promise<T> {
|
|
165
|
+
const base = agentServerUrl.replace(/\/$/, "");
|
|
166
|
+
const url = `${base}${path}`;
|
|
167
|
+
return await this.baseRequest(
|
|
168
|
+
url,
|
|
169
|
+
init,
|
|
170
|
+
{ "X-Session-API-Key": sessionApiKey, "Content-Type": "application/json" },
|
|
171
|
+
"json",
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private buildAgentEventFilterParams(opts?: {
|
|
176
|
+
timestampGte?: string;
|
|
177
|
+
timestampLt?: string;
|
|
178
|
+
kind?: string;
|
|
179
|
+
source?: string;
|
|
180
|
+
body?: string;
|
|
181
|
+
}): URLSearchParams {
|
|
182
|
+
const params = new URLSearchParams();
|
|
183
|
+
if (opts?.timestampGte) params.set("timestamp__gte", opts.timestampGte);
|
|
184
|
+
if (opts?.timestampLt) params.set("timestamp__lt", opts.timestampLt);
|
|
185
|
+
if (opts?.kind) params.set("kind", opts.kind);
|
|
186
|
+
if (opts?.source) params.set("source", opts.source);
|
|
187
|
+
if (opts?.body) params.set("body", opts.body);
|
|
188
|
+
return params;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async agentEventsCount(agentServerUrl: string, sessionApiKey: string, conversationId: string, opts?: {
|
|
192
|
+
timestampGte?: string;
|
|
193
|
+
timestampLt?: string;
|
|
194
|
+
kind?: string;
|
|
195
|
+
source?: string;
|
|
196
|
+
body?: string;
|
|
197
|
+
}): Promise<number> {
|
|
198
|
+
const qs = this.buildAgentEventFilterParams(opts).toString();
|
|
199
|
+
const suffix = qs ? `?${qs}` : "";
|
|
200
|
+
|
|
201
|
+
const n = await this.agentRequest<number>(
|
|
202
|
+
agentServerUrl,
|
|
203
|
+
sessionApiKey,
|
|
204
|
+
`/api/conversations/${encodeURIComponent(conversationId)}/events/count${suffix}`,
|
|
205
|
+
{ method: "GET" },
|
|
206
|
+
);
|
|
207
|
+
return Number(n);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async agentEventsSearch(agentServerUrl: string, sessionApiKey: string, conversationId: string, opts?: {
|
|
211
|
+
limit?: number;
|
|
212
|
+
sortOrder?: "TIMESTAMP" | "TIMESTAMP_DESC";
|
|
213
|
+
timestampGte?: string;
|
|
214
|
+
timestampLt?: string;
|
|
215
|
+
kind?: string;
|
|
216
|
+
source?: string;
|
|
217
|
+
body?: string;
|
|
218
|
+
}): Promise<Record<string, unknown>> {
|
|
219
|
+
const params = this.buildAgentEventFilterParams(opts);
|
|
220
|
+
|
|
221
|
+
// Cap limit to keep responses small and consistent across clients.
|
|
222
|
+
const rawLimit = opts?.limit ?? 50;
|
|
223
|
+
const safeLimit = Number.isFinite(rawLimit) ? Math.trunc(rawLimit) : 1;
|
|
224
|
+
const limit = Math.max(1, Math.min(AGENT_EVENTS_SEARCH_MAX_LIMIT, safeLimit));
|
|
225
|
+
params.set("limit", String(limit));
|
|
226
|
+
|
|
227
|
+
if (opts?.sortOrder) params.set("sort_order", opts.sortOrder);
|
|
228
|
+
|
|
229
|
+
return await this.agentRequest<Record<string, unknown>>(
|
|
230
|
+
agentServerUrl,
|
|
231
|
+
sessionApiKey,
|
|
232
|
+
`/api/conversations/${encodeURIComponent(conversationId)}/events/search?${params.toString()}`,
|
|
233
|
+
{ method: "GET" },
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async agentExecuteBash(agentServerUrl: string, sessionApiKey: string, command: string, cwd?: string): Promise<Record<string, unknown>> {
|
|
238
|
+
const payload: Record<string, unknown> = { command, timeout: 30 };
|
|
239
|
+
if (cwd) payload.cwd = cwd;
|
|
240
|
+
|
|
241
|
+
return await this.agentRequest<Record<string, unknown>>(
|
|
242
|
+
agentServerUrl,
|
|
243
|
+
sessionApiKey,
|
|
244
|
+
`/api/bash/execute_bash_command`,
|
|
245
|
+
{ method: "POST", body: JSON.stringify(payload) },
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
export type OpenHandsV1Options = OpenHandsOptions;
|
|
252
|
+
export { OpenHandsAPI as OpenHandsV1API };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openhands-automation",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Create and manage OpenHands automations - scheduled tasks that run in sandboxes. Use the prompt preset to create automations from natural language, or manage existing automations.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "OpenHands",
|
|
7
|
+
"email": "contact@all-hands.dev"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/OpenHands/extensions",
|
|
10
|
+
"repository": "https://github.com/OpenHands/extensions",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"automation",
|
|
14
|
+
"cron",
|
|
15
|
+
"scheduled-task",
|
|
16
|
+
"sandbox",
|
|
17
|
+
"openhands"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openhands-automation",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Create and manage OpenHands automations - scheduled tasks that run in sandboxes. Use the prompt preset to create automations from natural language, or manage existing automations.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "OpenHands",
|
|
7
|
+
"email": "contact@all-hands.dev"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/OpenHands/extensions",
|
|
10
|
+
"repository": "https://github.com/OpenHands/extensions",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"automation",
|
|
14
|
+
"cron",
|
|
15
|
+
"scheduled-task",
|
|
16
|
+
"sandbox",
|
|
17
|
+
"openhands"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openhands-automation",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Create and manage OpenHands automations - scheduled tasks that run in sandboxes. Use the prompt preset to create automations from natural language, or manage existing automations.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "OpenHands",
|
|
7
|
+
"email": "contact@all-hands.dev"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/OpenHands/extensions",
|
|
10
|
+
"repository": "https://github.com/OpenHands/extensions",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"automation",
|
|
14
|
+
"cron",
|
|
15
|
+
"scheduled-task",
|
|
16
|
+
"sandbox",
|
|
17
|
+
"openhands"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Automation Skill
|
|
2
|
+
|
|
3
|
+
Create and manage OpenHands automations — tasks that run in sandboxes on a cron schedule or triggered by webhook events (GitHub, custom services).
|
|
4
|
+
|
|
5
|
+
## Triggers
|
|
6
|
+
|
|
7
|
+
This skill is activated by keywords:
|
|
8
|
+
- `automation` / `automations`
|
|
9
|
+
- `scheduled task`
|
|
10
|
+
- `cron job` / `cron schedule`
|
|
11
|
+
- `webhook` / `webhooks`
|
|
12
|
+
- `event trigger`
|
|
13
|
+
- `github event`
|
|
14
|
+
- `pull request automation`
|
|
15
|
+
- `issue automation`
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **Prompt-based creation**: Create automations from a natural language prompt (recommended)
|
|
20
|
+
- **Event-triggered automations**: Trigger on GitHub events (PR opened, issue commented, push, etc.)
|
|
21
|
+
- **Custom webhooks**: Register webhooks for any service (Stripe, Slack, Linear, etc.)
|
|
22
|
+
- **JMESPath filters**: Match events based on payload content (labels, mentions, repos)
|
|
23
|
+
- **Automation management**: List, update, enable/disable, and delete automations
|
|
24
|
+
- **Manual dispatch**: Trigger automation runs on-demand
|
|
25
|
+
- **Custom automations**: For advanced users who need full control (see [references/custom-automation.md](references/custom-automation.md))
|
|
26
|
+
|
|
27
|
+
## API Base URL
|
|
28
|
+
|
|
29
|
+
Use an explicitly provided host first. When a local Agent Canvas automation server is running and no host is provided, use `http://localhost:8001/api/automation/v1`. Otherwise use the cloud default: `https://app.all-hands.dev/api/automation/v1`.
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Cron-Triggered Automation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/prompt" \
|
|
37
|
+
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
|
|
38
|
+
-H "Content-Type: application/json" \
|
|
39
|
+
-d '{
|
|
40
|
+
"name": "Daily Report",
|
|
41
|
+
"prompt": "Generate a daily status report and save it to the workspace",
|
|
42
|
+
"trigger": {"type": "cron", "schedule": "0 9 * * 1-5", "timezone": "UTC"}
|
|
43
|
+
}'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Event-Triggered Automation (GitHub)
|
|
47
|
+
|
|
48
|
+
Respond to @openhands mentions in issue comments:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/prompt" \
|
|
52
|
+
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
|
|
53
|
+
-H "Content-Type: application/json" \
|
|
54
|
+
-d '{
|
|
55
|
+
"name": "Mention Responder",
|
|
56
|
+
"prompt": "Analyze the issue context and respond helpfully",
|
|
57
|
+
"trigger": {
|
|
58
|
+
"type": "event",
|
|
59
|
+
"source": "github",
|
|
60
|
+
"on": "issue_comment.created",
|
|
61
|
+
"filter": "icontains(comment.body, '\''@openhands'\'')"
|
|
62
|
+
}
|
|
63
|
+
}'
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Auto-review PRs with the "openhands" label:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
curl -X POST "https://app.all-hands.dev/api/automation/v1/preset/prompt" \
|
|
70
|
+
-H "Authorization: Bearer ${OPENHANDS_API_KEY}" \
|
|
71
|
+
-H "Content-Type: application/json" \
|
|
72
|
+
-d '{
|
|
73
|
+
"name": "Auto Review PRs",
|
|
74
|
+
"prompt": "Review this PR for code quality and best practices",
|
|
75
|
+
"trigger": {
|
|
76
|
+
"type": "event",
|
|
77
|
+
"source": "github",
|
|
78
|
+
"on": "pull_request.labeled",
|
|
79
|
+
"filter": "contains(pull_request.labels[].name, '\''openhands'\'')"
|
|
80
|
+
}
|
|
81
|
+
}'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The service handles SDK code generation, tarball packaging, upload, and automation creation automatically.
|
|
85
|
+
|
|
86
|
+
## See Also
|
|
87
|
+
|
|
88
|
+
- [SKILL.md](SKILL.md) — Full API reference, agent behavior rules, event keys, filters, and examples
|
|
89
|
+
- [references/custom-automation.md](references/custom-automation.md) — Reference for custom automations with user-provided SDK scripts
|