@openhands/extensions 0.5.0 → 0.7.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/.github/workflows/pypi-publish.yml +104 -0
- package/.github/workflows/tests.yml +6 -0
- package/.release-please-manifest.json +1 -1
- package/AGENTS.md +1 -1
- package/README.md +34 -4
- package/integrations/README.md +25 -9
- package/integrations/catalog/airtable.json +16 -10
- package/integrations/catalog/apify.json +0 -2
- package/integrations/catalog/asana.json +33 -0
- package/integrations/catalog/atlassian.json +5 -8
- package/integrations/catalog/bitbucket.json +34 -0
- package/integrations/catalog/box.json +34 -0
- package/integrations/catalog/brave-search.json +1 -2
- package/integrations/catalog/browser-mcp.json +0 -3
- package/integrations/catalog/canva.json +31 -0
- package/integrations/catalog/clickhouse.json +1 -2
- package/integrations/catalog/cloudflare-bindings.json +5 -8
- package/integrations/catalog/cloudflare-browser-rendering.json +5 -8
- package/integrations/catalog/cloudflare-builds.json +6 -9
- package/integrations/catalog/cloudflare-docs.json +4 -7
- package/integrations/catalog/cloudflare-observability.json +5 -8
- package/integrations/catalog/confluence.json +33 -0
- package/integrations/catalog/datadog.json +34 -0
- package/integrations/catalog/deepwiki.json +3 -7
- package/integrations/catalog/discord.json +34 -0
- package/integrations/catalog/elevenlabs.json +27 -28
- package/integrations/catalog/everything.json +0 -2
- package/integrations/catalog/exa.json +0 -2
- package/integrations/catalog/fetch.json +0 -2
- package/integrations/catalog/figma.json +35 -9
- package/integrations/catalog/filesystem.json +0 -3
- package/integrations/catalog/firecrawl.json +0 -2
- package/integrations/catalog/git.json +0 -3
- package/integrations/catalog/github.json +34 -10
- package/integrations/catalog/gmail.json +33 -0
- package/integrations/catalog/google-calendar.json +33 -0
- package/integrations/catalog/google-docs.json +33 -0
- package/integrations/catalog/google-drive.json +33 -0
- package/integrations/catalog/google-sheets.json +33 -0
- package/integrations/catalog/hubspot.json +34 -0
- package/integrations/catalog/huggingface.json +1 -2
- package/integrations/catalog/intercom.json +34 -0
- package/integrations/catalog/jira.json +33 -0
- package/integrations/catalog/kagi.json +2 -3
- package/integrations/catalog/linear.json +24 -16
- package/integrations/catalog/memory.json +0 -2
- package/integrations/catalog/microsoft-outlook.json +33 -0
- package/integrations/catalog/microsoft-teams.json +33 -0
- package/integrations/catalog/miro.json +42 -0
- package/integrations/catalog/monday.json +42 -0
- package/integrations/catalog/mongodb.json +1 -2
- package/integrations/catalog/neon.json +0 -2
- package/integrations/catalog/netlify.json +33 -0
- package/integrations/catalog/notion.json +30 -10
- package/integrations/catalog/obsidian.json +1 -3
- package/integrations/catalog/okta.json +33 -0
- package/integrations/catalog/onedrive.json +33 -0
- package/integrations/catalog/ordinal.json +33 -0
- package/integrations/catalog/paypal.json +5 -8
- package/integrations/catalog/playwright.json +0 -2
- package/integrations/catalog/posthog.json +38 -0
- package/integrations/catalog/quickbooks.json +86 -0
- package/integrations/catalog/redis.json +1 -3
- package/integrations/catalog/resend.json +1 -2
- package/integrations/catalog/salesforce.json +44 -0
- package/integrations/catalog/sentry.json +47 -14
- package/integrations/catalog/sequential-thinking.json +0 -2
- package/integrations/catalog/sharepoint.json +33 -0
- package/integrations/catalog/slack.json +49 -10
- package/integrations/catalog/stripe.json +39 -14
- package/integrations/catalog/supabase.json +31 -9
- package/integrations/catalog/tavily.json +0 -2
- package/integrations/catalog/time.json +0 -2
- package/integrations/catalog/trello.json +34 -0
- package/integrations/catalog/vercel.json +33 -0
- package/integrations/catalog/webflow.json +34 -0
- package/integrations/catalog/xero.json +33 -0
- package/integrations/catalog/zoom.json +33 -0
- package/integrations/catalog-index.js +151 -0
- package/integrations/catalog.schema.json +255 -0
- package/integrations/index.d.ts +49 -69
- package/integrations/index.js +36 -206
- package/marketplaces/openhands-extensions.json +40 -2
- package/package.json +4 -7
- package/plugins/cobol-modernization/README.md +3 -3
- package/plugins/cobol-modernization/skills/{cobol-modernization-overview → cobol-modernization}/SKILL.md +1 -1
- package/plugins/magic-test/skills/magic-word/SKILL.md +1 -0
- package/plugins/migration-scoring/README.md +1 -1
- package/plugins/pr-review/scripts/prompt.py +1 -1
- package/pyproject.toml +18 -3
- package/python/openhands_extensions/__init__.py +24 -0
- package/python/openhands_extensions/_version.py +25 -0
- package/python/openhands_extensions/integrations.py +92 -0
- package/release-please-config.json +2 -1
- package/scripts/build-integration-catalog.mjs +45 -0
- package/skills/agent-canvas-environment/.plugin/plugin.json +19 -0
- package/skills/agent-canvas-environment/README.md +5 -0
- package/skills/agent-canvas-environment/SKILL.md +202 -0
- package/skills/bitbucket/README.md +23 -40
- package/skills/bitbucket/SKILL.md +43 -31
- package/skills/bitbucket-cloud/.plugin/plugin.json +18 -0
- package/skills/bitbucket-cloud/README.md +15 -0
- package/skills/bitbucket-cloud/SKILL.md +46 -0
- package/skills/bitbucket-data-center/.plugin/plugin.json +19 -0
- package/skills/bitbucket-data-center/README.md +20 -0
- package/skills/bitbucket-data-center/SKILL.md +53 -0
- package/skills/code-review/SKILL.md +1 -1
- package/skills/code-review/references/supply-chain-security.md +2 -2
- package/skills/github-pr-reviewer/references/state-schema.md +18 -4
- package/skills/github-pr-reviewer/scripts/main.py +66 -12
- package/skills/github-repo-monitor/references/state-schema.md +11 -4
- package/skills/github-repo-monitor/scripts/main.py +67 -19
- package/skills/github-repo-monitor/tests/test_main.py +67 -8
- package/skills/index.js +34 -8
- package/skills/openhands-api/README.md +5 -1
- package/skills/openhands-api/SKILL.md +74 -5
- package/skills/openhands-automation/SKILL.md +3 -1
- package/skills/openhands-automation/references/custom-automation.md +166 -0
- package/skills/openhands-sdk/SKILL.md +8 -3
- package/skills/slack-channel-monitor/README.md +3 -3
- package/skills/slack-channel-monitor/SKILL.md +3 -2
- package/skills/slack-channel-monitor/references/state-schema.md +11 -4
- package/skills/slack-channel-monitor/scripts/main.py +111 -41
- package/tests/test_catalog_schema.py +47 -0
- package/tests/test_catalogs.py +47 -3
- package/tests/test_integration_catalog_in_sync.py +252 -0
- package/tests/test_slack_channel_monitor.py +142 -0
- package/tests/test_version_alignment.py +64 -0
- package/integrations/logos.d.ts +0 -5
- package/integrations/logos.js +0 -94
- package/integrations/oauth-provider-catalog.js +0 -553
- package/integrations/oauth-provider-registration-defaults.js +0 -610
- /package/plugins/cobol-modernization/skills/{mainfraime-removal → mainframe-removal}/SKILL.md +0 -0
- /package/plugins/cobol-modernization/skills/{mainfraime-removal → mainframe-removal}/references/cics-transformation-examples.md +0 -0
- /package/plugins/migration-scoring/skills/{migration-scoring-overview → migration-scoring}/SKILL.md +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-canvas-environment
|
|
3
|
+
description: Work effectively inside a local Agent Canvas environment, including local agent-server auth, frontend/backend port discovery, safe workspace hygiene, and delegating work to a new local conversation through POST /api/conversations.
|
|
4
|
+
triggers:
|
|
5
|
+
- agent canvas
|
|
6
|
+
- agent-canvas
|
|
7
|
+
- local conversation
|
|
8
|
+
- delegate local conversation
|
|
9
|
+
- session api key
|
|
10
|
+
- X-Session-API-Key
|
|
11
|
+
- localhost:8001
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Agent Canvas Environment
|
|
15
|
+
|
|
16
|
+
Use this skill when running inside or alongside a local Agent Canvas stack, especially when the user asks to inspect the local backend, create or monitor local conversations, or delegate work to another local conversation.
|
|
17
|
+
|
|
18
|
+
## Core rules
|
|
19
|
+
|
|
20
|
+
- Treat the local Agent Canvas backend as an agent-server API, usually `http://localhost:8001`.
|
|
21
|
+
- Treat the local UI as a separate frontend, usually `http://localhost:8000`.
|
|
22
|
+
- Do not print session API keys. Pass them directly in `X-Session-API-Key`.
|
|
23
|
+
- Trust any runtime-services block or explicit user-provided host over default ports.
|
|
24
|
+
- Before mutating a repository, check `git status -sb`. If a worktree has unrelated changes, use a separate worktree or clone.
|
|
25
|
+
- When delegating, write a self-contained prompt. The new conversation does not inherit the current chat context.
|
|
26
|
+
|
|
27
|
+
## Find the session key
|
|
28
|
+
|
|
29
|
+
Use the first available value, without echoing it:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
KEY="${SESSION_API_KEY:-${OH_SESSION_API_KEYS_0:-${LOCAL_BACKEND_API_KEY:-}}}"
|
|
33
|
+
if [ -z "$KEY" ] && [ -f "$HOME/.openhands/agent-canvas/api-key.txt" ]; then
|
|
34
|
+
KEY="$(tr -d '\n' < "$HOME/.openhands/agent-canvas/api-key.txt")"
|
|
35
|
+
fi
|
|
36
|
+
test -n "$KEY" || { echo "No Agent Canvas session API key found" >&2; exit 1; }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Validate backend access:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
curl -sS -o /tmp/agent-canvas-conversations.json -w '%{http_code}\n' \
|
|
43
|
+
-H "X-Session-API-Key: $KEY" \
|
|
44
|
+
http://localhost:8001/api/conversations/search
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
HTTP `200` means the backend and key work.
|
|
48
|
+
|
|
49
|
+
## Delegate to a local conversation
|
|
50
|
+
|
|
51
|
+
Use `POST /api/conversations` with:
|
|
52
|
+
|
|
53
|
+
- the **encrypted** `agent_settings` from `GET /api/settings` (with `X-Expose-Secrets: encrypted`), which carries the real Fernet-encrypted `llm.api_key`, the existing `agent_context`, and the agent kind — so you never handle plaintext credentials and you don't drop the caller's skill/context config
|
|
54
|
+
- `secrets_encrypted: true` so the agent-server decrypts that `api_key` server-side
|
|
55
|
+
- the exec tool set merged into `agent_settings.tools` (and `task_tool_set` when you enable sub-agents)
|
|
56
|
+
- `tool_module_qualnames` for any non-SDK tools (e.g. `canvas_ui`)
|
|
57
|
+
- `agent_context.load_public_skills`/`load_user_skills`/`load_project_skills` set to `true` if the delegated agent should inherit bundled/user/project skills
|
|
58
|
+
- a fresh absolute workspace directory
|
|
59
|
+
- `initial_message.run: true`
|
|
60
|
+
- `worktree: false` when the workspace is already isolated
|
|
61
|
+
|
|
62
|
+
### Credential handling — important
|
|
63
|
+
|
|
64
|
+
`GET /api/settings` (default) **masks** every credential — `llm.api_key` comes back as the literal string `"**********"`. If you forward that verbatim, the new conversation authenticates with the placeholder and fails immediately with `LLMAuthenticationError` (`You must provide an API key`).
|
|
65
|
+
|
|
66
|
+
The supported way to obtain forwardable credentials is the **`X-Expose-Secrets: encrypted`** request header. With it, `/api/settings` returns the real `llm.api_key` as a **Fernet-encrypted token** (starts with `gAAAAA`) intended to be sent back to the server with `secrets_encrypted: true`; the agent-server's `decrypt_incoming_llm_secrets` decrypts it server-side. Do **not** read `~/.openhands/profiles/*.json` directly — that is brittle (the caller may not share the backend's home directory, `active_profile` may be null, the profile store may live elsewhere).
|
|
67
|
+
|
|
68
|
+
Two working approaches:
|
|
69
|
+
|
|
70
|
+
1. **`agent_profile_id` (simplest, but no tools)** — send only `agent_profile_id: "<uuid>"` (from `GET /api/agent-profiles` → the profile whose `id` equals `active_agent_profile_id` from `/api/settings`). The server resolves the LLM key + agent kind from the profile. Mutually exclusive with `agent`/`agent_settings`, and the `openhands` agent-profile schema forbids `tools`/`include_default_tools`, so the conversation gets **zero exec tools** this way. Use only when the task needs no tools.
|
|
71
|
+
|
|
72
|
+
2. **Encrypted `agent_settings` (full tools, preserves context)** — start from the encrypted `/api/settings` `agent_settings` payload, drop `schema_version` and `mcp_config` (to avoid MCP-connection failures at creation time), merge in the exec tool set and `load_*_skills` flags, and send with `secrets_encrypted: true`. This is the pattern for real delegated work.
|
|
73
|
+
|
|
74
|
+
Template (full tools, preserves context):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
set -euo pipefail
|
|
78
|
+
|
|
79
|
+
BASE="${AGENT_CANVAS_BACKEND:-http://localhost:8001}"
|
|
80
|
+
KEY="${SESSION_API_KEY:-${OH_SESSION_API_KEYS_0:-${LOCAL_BACKEND_API_KEY:-}}}"
|
|
81
|
+
if [ -z "$KEY" ] && [ -f "$HOME/.openhands/agent-canvas/api-key.txt" ]; then
|
|
82
|
+
KEY="$(tr -d '\n' < "$HOME/.openhands/agent-canvas/api-key.txt")"
|
|
83
|
+
fi
|
|
84
|
+
test -n "$KEY" || { echo "No Agent Canvas session API key found" >&2; exit 1; }
|
|
85
|
+
|
|
86
|
+
WORKDIR="${WORKDIR:-$HOME/workspace/delegated/$(date +%Y%m%d-%H%M%S)}"
|
|
87
|
+
mkdir -p "$WORKDIR"
|
|
88
|
+
|
|
89
|
+
# Fetch the agent_settings with ENCRYPTED secrets exposed. This returns the
|
|
90
|
+
# real llm.api_key as a Fernet token (gAAAAA...) plus the existing
|
|
91
|
+
# agent_context/agent kind, so we preserve the caller's config and never
|
|
92
|
+
# handle plaintext credentials.
|
|
93
|
+
SETTINGS_JSON="$(curl -sS -H "X-Session-API-Key: $KEY" -H "X-Expose-Secrets: encrypted" "$BASE/api/settings")"
|
|
94
|
+
|
|
95
|
+
PROMPT='Write a complete, task-specific prompt here. Include repo, branch, constraints, validation, and expected report.'
|
|
96
|
+
|
|
97
|
+
PAYLOAD="$(jq -n --argjson settings "$SETTINGS_JSON" --arg prompt "$PROMPT" --arg workdir "$WORKDIR" '
|
|
98
|
+
# Start from the encrypted agent_settings so llm.api_key (Fernet token),
|
|
99
|
+
# agent_kind, and agent_context are preserved. Drop schema_version and
|
|
100
|
+
# mcp_config (MCP servers can fail to connect at creation time; the profile
|
|
101
|
+
# can be re-resolved later if needed).
|
|
102
|
+
def base_agent_settings:
|
|
103
|
+
($settings.agent_settings // {})
|
|
104
|
+
| del(.schema_version)
|
|
105
|
+
| del(.mcp_config);
|
|
106
|
+
|
|
107
|
+
# Merge the exec tool set into the existing tools list. Include task_tool_set
|
|
108
|
+
# when sub-agents are enabled — enable_sub_agents alone does not expose the
|
|
109
|
+
# delegation tool; Agent Canvas adds task_tool_set for that.
|
|
110
|
+
def with_tools:
|
|
111
|
+
.tools = ((.tools // []) + [
|
|
112
|
+
{name: "terminal", params: {}},
|
|
113
|
+
{name: "file_editor", params: {}},
|
|
114
|
+
{name: "task_tracker", params: {}},
|
|
115
|
+
{name: "browser_tool_set", params: {}},
|
|
116
|
+
{name: "canvas_ui", params: {}}
|
|
117
|
+
] + (if .enable_sub_agents then [{name: "task_tool_set", params: {}}] else [] end)
|
|
118
|
+
| unique_by(.name));
|
|
119
|
+
|
|
120
|
+
# Preserve the existing agent_context and enable skill loading for the
|
|
121
|
+
# delegated agent (defaults are false, so set these explicitly).
|
|
122
|
+
def with_skill_loading:
|
|
123
|
+
.agent_context = ((.agent_context // {}) + {
|
|
124
|
+
load_public_skills: true,
|
|
125
|
+
load_user_skills: true,
|
|
126
|
+
load_project_skills: true
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
($settings.conversation_settings // {}) as $conv |
|
|
130
|
+
{
|
|
131
|
+
secrets_encrypted: true,
|
|
132
|
+
agent_settings: (base_agent_settings | with_tools | with_skill_loading),
|
|
133
|
+
tool_module_qualnames: { canvas_ui: "canvas_ui_tool" },
|
|
134
|
+
workspace: {kind: "LocalWorkspace", working_dir: $workdir},
|
|
135
|
+
confirmation_policy: {kind: "NeverConfirm"},
|
|
136
|
+
# Delegated tasks usually need more than the SDK default of 80 iterations;
|
|
137
|
+
# default to the caller's conversation_settings value (1000 in Agent Canvas)
|
|
138
|
+
# so long-running tasks aren't cut off prematurely. Override per-task if needed.
|
|
139
|
+
max_iterations: (($conv.max_iterations // 1000) | if . == null then 1000 else . end),
|
|
140
|
+
stuck_detection: true,
|
|
141
|
+
autotitle: true,
|
|
142
|
+
worktree: false,
|
|
143
|
+
initial_message: {
|
|
144
|
+
role: "user",
|
|
145
|
+
content: [{type: "text", text: $prompt}],
|
|
146
|
+
run: true
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
')"
|
|
150
|
+
|
|
151
|
+
curl -sS -X POST "$BASE/api/conversations" \
|
|
152
|
+
-H "Content-Type: application/json" \
|
|
153
|
+
-H "X-Session-API-Key: $KEY" \
|
|
154
|
+
--data-binary "$PAYLOAD" | jq '{id, title, execution_status, workspace}'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Verify the new conversation actually has tools and is running (not errored):
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
CID="<conversation_id>"
|
|
161
|
+
curl -sS -H "X-Session-API-Key: $KEY" "$BASE/api/conversations/$CID" \
|
|
162
|
+
| jq '{execution_status, tools: [.agent.tools[]?.name]}'
|
|
163
|
+
curl -sS -H "X-Session-API-Key: $KEY" "$BASE/api/conversations/$CID/events/search?limit=20" \
|
|
164
|
+
| jq '[.events[]? | select(.kind=="ConversationErrorEvent") | .code] // []'
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`execution_status` should be `running`/`idle`/`finished` (not `error`), `tools` should list the exec tools, and there should be no `ConversationErrorEvent`.
|
|
168
|
+
|
|
169
|
+
If MCP servers configured in the profile are unreachable, conversation creation can fail with `MCP Connection Failure`; the template drops `mcp_config` from the forwarded `agent_settings` to avoid that.
|
|
170
|
+
|
|
171
|
+
Report both links:
|
|
172
|
+
|
|
173
|
+
- UI: `http://localhost:8000/conversations/<conversation_id>`
|
|
174
|
+
- API: `http://localhost:8001/api/conversations/<conversation_id>`
|
|
175
|
+
|
|
176
|
+
## Monitor a delegated conversation
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
CID="<conversation_id>"
|
|
180
|
+
curl -sS -H "X-Session-API-Key: $KEY" "$BASE/api/conversations/$CID" \
|
|
181
|
+
| jq '{id, title, execution_status, updated_at, workspace, agent_kind: .agent.kind, current_model_id, current_model_name}'
|
|
182
|
+
|
|
183
|
+
curl -sS -H "X-Session-API-Key: $KEY" "$BASE/api/conversations/$CID/events/search?limit=20" \
|
|
184
|
+
| jq '.events // .items // .'
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Terminal statuses commonly include `idle`, `running`, `finished`, `error`, `stuck`, and `stopped`.
|
|
188
|
+
|
|
189
|
+
## Prompt checklist for delegation
|
|
190
|
+
|
|
191
|
+
Include:
|
|
192
|
+
|
|
193
|
+
- repository owner/name and local path if relevant
|
|
194
|
+
- branch, PR, issue, or Linear ticket identifiers
|
|
195
|
+
- current status and known blockers
|
|
196
|
+
- exact files or subsystems in scope
|
|
197
|
+
- dirty-worktree warnings and paths not to touch
|
|
198
|
+
- whether to push, open a PR, or only report
|
|
199
|
+
- checks/tests to run
|
|
200
|
+
- expected final report format
|
|
201
|
+
|
|
202
|
+
Do not rely on the new conversation knowing anything from the current thread.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Bitbucket
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Bitbucket integration **hub** skill. It detects whether the repository is on Bitbucket
|
|
4
|
+
Cloud or Bitbucket Data Center and directs the agent to the matching detailed skill.
|
|
4
5
|
|
|
5
6
|
## Triggers
|
|
6
7
|
|
|
@@ -9,42 +10,24 @@ This skill is activated by the following keywords:
|
|
|
9
10
|
- `bitbucket`
|
|
10
11
|
- `git`
|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Atlassian's Bitbucket Cloud docs recommend avoiding long-lived credentials in the remote URL when possible. Their API token examples use either `https://{bitbucket_username}:{api_token}@...` or `https://x-bitbucket-api-token-auth:{api_token}@...`; OpenHands users should only construct those URLs on demand, with proper URL encoding.
|
|
36
|
-
|
|
37
|
-
Here are some instructions for pushing, but ONLY do this if the user asks you to:
|
|
38
|
-
* NEVER push directly to the `main` or `master` branch
|
|
39
|
-
* Git config (username and email) is pre-set. Do not modify.
|
|
40
|
-
* You may already be on a branch starting with `openhands-workspace`. Create a new branch with a better name before pushing.
|
|
41
|
-
* Use the `create_bitbucket_pr` tool to create a pull request, if you haven't already
|
|
42
|
-
* Once you've created your own branch or a pull request, continue to update it. Do NOT create a new one unless you are explicitly asked to. Update the PR title and description as necessary, but don't change the branch name.
|
|
43
|
-
* Use the main branch as the base branch, unless the user requests otherwise
|
|
44
|
-
* After opening or updating a pull request, send the user a short message with a link to the pull request.
|
|
45
|
-
* Do NOT mark a pull request as ready to review unless the user explicitly says so
|
|
46
|
-
* Do all of the above in as few steps as possible. E.g. you could push changes with one step by running the following bash commands:
|
|
47
|
-
```bash
|
|
48
|
-
git remote -v && git branch # to find the current org, repo and branch
|
|
49
|
-
git checkout -b create-widget && git add . && git commit -m "Create widget" && git push -u origin create-widget
|
|
50
|
-
```
|
|
13
|
+
## Why a hub skill?
|
|
14
|
+
|
|
15
|
+
Bitbucket ships as two products that behave differently — **Bitbucket Cloud**
|
|
16
|
+
(`bitbucket.org`) and **Bitbucket Data Center** (self-hosted Bitbucket Server). They use
|
|
17
|
+
different token environment variables, REST APIs, repository identifiers, git remote URL
|
|
18
|
+
formats, and pull request tools.
|
|
19
|
+
|
|
20
|
+
This hub triggers broadly (on `git`/`bitbucket`) so it loads for any Bitbucket task — even
|
|
21
|
+
when the words "data center" never appear. It then:
|
|
22
|
+
|
|
23
|
+
1. **Detects** the environment by checking which token variable is present
|
|
24
|
+
(`BITBUCKET_DATA_CENTER_TOKEN` → Data Center, else `BITBUCKET_TOKEN` → Cloud). The check
|
|
25
|
+
is case-insensitive so it is robust to env-var casing differences.
|
|
26
|
+
2. **Hands off** to the matching detailed skill via the `invoke_skill` tool:
|
|
27
|
+
- Bitbucket Cloud → [`bitbucket-cloud`](../bitbucket-cloud/)
|
|
28
|
+
- Bitbucket Data Center → [`bitbucket-data-center`](../bitbucket-data-center/)
|
|
29
|
+
|
|
30
|
+
The hub also carries a small quick-reference table as a fallback in case the detailed skill
|
|
31
|
+
cannot be loaded.
|
|
32
|
+
|
|
33
|
+
See [`SKILL.md`](SKILL.md) for the full content.
|
|
@@ -1,45 +1,57 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bitbucket
|
|
3
|
-
description:
|
|
3
|
+
description: Bitbucket integration hub. Detects whether the repository is on Bitbucket Cloud or Bitbucket Data Center and directs you to the matching detailed skill (bitbucket-cloud or bitbucket-data-center). Use for any Bitbucket repository or pull request task.
|
|
4
4
|
triggers:
|
|
5
5
|
- bitbucket
|
|
6
6
|
- git
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
You
|
|
10
|
-
|
|
9
|
+
You are working with **Bitbucket**, which ships as two distinct products that behave
|
|
10
|
+
differently:
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
</IMPORTANT>
|
|
12
|
+
- **Bitbucket Cloud** (`bitbucket.org`) — authenticates with the `BITBUCKET_TOKEN`
|
|
13
|
+
environment variable.
|
|
14
|
+
- **Bitbucket Data Center** (self-hosted Bitbucket Server) — authenticates with the
|
|
15
|
+
`BITBUCKET_DATA_CENTER_TOKEN` environment variable.
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
They use different REST APIs, repository identifiers, git remote URL formats, and pull
|
|
18
|
+
request tools, so you must first determine which one you are on, then load the matching
|
|
19
|
+
detailed skill for full instructions.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
## Step 1 — Detect which Bitbucket you are on
|
|
22
|
+
|
|
23
|
+
Check which token environment variable is present. Environment variable names are
|
|
24
|
+
case-sensitive, so look for it case-insensitively:
|
|
21
25
|
|
|
22
26
|
```bash
|
|
23
|
-
|
|
24
|
-
BB_PASS="${BITBUCKET_TOKEN#*:}" && \
|
|
25
|
-
ENCODED_USER=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$BB_USER") && \
|
|
26
|
-
ENCODED_PASS=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$BB_PASS") && \
|
|
27
|
-
git remote set-url origin "https://${ENCODED_USER}:${ENCODED_PASS}@bitbucket.org/username/repo.git"
|
|
27
|
+
env | grep -i 'bitbucket' || echo "no bitbucket token found"
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
- If a **`BITBUCKET_DATA_CENTER_TOKEN`** variable is set (in any letter case) → you are on
|
|
31
|
+
**Bitbucket Data Center**.
|
|
32
|
+
- Otherwise, if a **`BITBUCKET_TOKEN`** variable is set → you are on **Bitbucket Cloud**.
|
|
33
|
+
- If neither is set, ask the user how they authenticate to Bitbucket before proceeding.
|
|
34
|
+
|
|
35
|
+
When you reference the token later, use the exact variable name (and letter case) that
|
|
36
|
+
actually exists in the environment.
|
|
37
|
+
|
|
38
|
+
## Step 2 — Load the detailed skill
|
|
39
|
+
|
|
40
|
+
Once you know the environment, use the `invoke_skill` tool to load the matching skill for
|
|
41
|
+
full instructions on API calls, authenticated git remotes, and opening pull requests:
|
|
42
|
+
|
|
43
|
+
- Bitbucket Cloud → invoke the **`bitbucket-cloud`** skill.
|
|
44
|
+
- Bitbucket Data Center → invoke the **`bitbucket-data-center`** skill.
|
|
45
|
+
|
|
46
|
+
## Quick reference (fallback)
|
|
47
|
+
|
|
48
|
+
If you are unable to load the detailed skill, these are the essentials. Always use the
|
|
49
|
+
Bitbucket API (not a web browser) and always use the listed PR tool to open a pull request.
|
|
50
|
+
|
|
51
|
+
| | Bitbucket Cloud | Bitbucket Data Center |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| Token env var | `BITBUCKET_TOKEN` | `BITBUCKET_DATA_CENTER_TOKEN` |
|
|
54
|
+
| Host | `bitbucket.org` | self-hosted domain |
|
|
55
|
+
| REST API base | `https://api.bitbucket.org/2.0` | `https://<host>/rest/api/1.0` |
|
|
56
|
+
| Repository identifier | `workspace/repo_slug` | `PROJECT/repo_slug` (project key) |
|
|
57
|
+
| Pull request tool | `create_bitbucket_pr` | `create_bitbucket_data_center_pr` |
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bitbucket-cloud",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Bitbucket Cloud (bitbucket.org) specifics — authenticate with BITBUCKET_TOKEN, use the REST API v2, workspace/repo_slug repositories, and the create_bitbucket_pr tool. Loaded on demand by the bitbucket skill once a Cloud environment is detected.",
|
|
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
|
+
"bitbucket",
|
|
14
|
+
"bitbucket-cloud",
|
|
15
|
+
"git",
|
|
16
|
+
"pull-request"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Bitbucket Cloud
|
|
2
|
+
|
|
3
|
+
Bitbucket Cloud (`bitbucket.org`) specifics — `BITBUCKET_TOKEN` auth, REST API v2,
|
|
4
|
+
`workspace/repo_slug` repositories, and the `create_bitbucket_pr` tool.
|
|
5
|
+
|
|
6
|
+
## Triggers
|
|
7
|
+
|
|
8
|
+
This skill has no auto-injection triggers. It is **invoke-only**: it is loaded on demand
|
|
9
|
+
via the `invoke_skill` tool, normally by the [`bitbucket`](../bitbucket/) hub skill after
|
|
10
|
+
it detects a Bitbucket Cloud environment (i.e. `BITBUCKET_TOKEN` is set).
|
|
11
|
+
|
|
12
|
+
## Details
|
|
13
|
+
|
|
14
|
+
See [`SKILL.md`](SKILL.md) for the full content, including authenticated git remote
|
|
15
|
+
construction and pull request instructions.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bitbucket-cloud
|
|
3
|
+
description: Bitbucket Cloud (bitbucket.org) specifics — authenticate with BITBUCKET_TOKEN, use the REST API v2, workspace/repo_slug repositories, and the create_bitbucket_pr tool. Loaded on demand by the bitbucket skill once a Cloud environment is detected.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are working with **Bitbucket Cloud** (`bitbucket.org`). You have access to an
|
|
7
|
+
environment variable, `BITBUCKET_TOKEN`, which allows you to interact with the Bitbucket
|
|
8
|
+
Cloud API.
|
|
9
|
+
|
|
10
|
+
- REST API base URL: `https://api.bitbucket.org/2.0`
|
|
11
|
+
- Repository identifier format: `workspace/repo_slug`
|
|
12
|
+
|
|
13
|
+
<IMPORTANT>
|
|
14
|
+
You can use `curl` with the `BITBUCKET_TOKEN` to interact with Bitbucket's API.
|
|
15
|
+
ALWAYS use the Bitbucket API for operations instead of a web browser.
|
|
16
|
+
ALWAYS use the `create_bitbucket_pr` tool to open a pull request
|
|
17
|
+
</IMPORTANT>
|
|
18
|
+
|
|
19
|
+
Only rewrite the Bitbucket remote if a push actually fails with authentication errors and the user has asked you to push. Do not proactively rewrite `origin`. OpenHands OSS commonly stores `BITBUCKET_TOKEN` in the same unencoded `user:token` form used by commands such as `curl --user "$BITBUCKET_TOKEN" ...`, so keep it in that form unless you truly need to embed it in a Git remote URL.
|
|
20
|
+
|
|
21
|
+
If you need a non-interactive HTTPS remote URL, split `BITBUCKET_TOKEN` on the first `:` and URL-encode each part before calling `git remote set-url`. This avoids breaking usernames or emails that contain reserved URL characters such as `@`:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
BB_USER="${BITBUCKET_TOKEN%%:*}" && \
|
|
25
|
+
BB_PASS="${BITBUCKET_TOKEN#*:}" && \
|
|
26
|
+
ENCODED_USER=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$BB_USER") && \
|
|
27
|
+
ENCODED_PASS=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$BB_PASS") && \
|
|
28
|
+
git remote set-url origin "https://${ENCODED_USER}:${ENCODED_PASS}@bitbucket.org/username/repo.git"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Atlassian's Bitbucket Cloud docs recommend avoiding long-lived credentials in the remote URL when possible. Their API token examples use either `https://{bitbucket_username}:{api_token}@...` or `https://x-bitbucket-api-token-auth:{api_token}@...`; OpenHands users should only construct those URLs on demand, with proper URL encoding.
|
|
32
|
+
|
|
33
|
+
Here are some instructions for pushing, but ONLY do this if the user asks you to:
|
|
34
|
+
* NEVER push directly to the `main` or `master` branch
|
|
35
|
+
* Git config (username and email) is pre-set. Do not modify.
|
|
36
|
+
* You may already be on a branch starting with `openhands-workspace`. Create a new branch with a better name before pushing.
|
|
37
|
+
* Use the `create_bitbucket_pr` tool to create a pull request, if you haven't already
|
|
38
|
+
* Once you've created your own branch or a pull request, continue to update it. Do NOT create a new one unless you are explicitly asked to. Update the PR title and description as necessary, but don't change the branch name.
|
|
39
|
+
* Use the main branch as the base branch, unless the user requests otherwise
|
|
40
|
+
* After opening or updating a pull request, send the user a short message with a link to the pull request.
|
|
41
|
+
* Do NOT mark a pull request as ready to review unless the user explicitly says so
|
|
42
|
+
* Do all of the above in as few steps as possible. E.g. you could push changes with one step by running the following bash commands:
|
|
43
|
+
```bash
|
|
44
|
+
git remote -v && git branch # to find the current org, repo and branch
|
|
45
|
+
git checkout -b create-widget && git add . && git commit -m "Create widget" && git push -u origin create-widget
|
|
46
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bitbucket-data-center",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Bitbucket Data Center (self-hosted Bitbucket Server) specifics — authenticate with BITBUCKET_DATA_CENTER_TOKEN, use the REST API 1.0, PROJECT/repo_slug repositories, scm/ git remotes, and the create_bitbucket_data_center_pr tool. Loaded on demand by the bitbucket skill once a Data Center environment is detected.",
|
|
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
|
+
"bitbucket",
|
|
14
|
+
"bitbucket-data-center",
|
|
15
|
+
"bitbucket-server",
|
|
16
|
+
"git",
|
|
17
|
+
"pull-request"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Bitbucket Data Center
|
|
2
|
+
|
|
3
|
+
Bitbucket Data Center (self-hosted Bitbucket Server) specifics — `BITBUCKET_DATA_CENTER_TOKEN`
|
|
4
|
+
auth, REST API 1.0, `PROJECT/repo_slug` repositories, `scm/` git remotes, and the
|
|
5
|
+
`create_bitbucket_data_center_pr` tool.
|
|
6
|
+
|
|
7
|
+
## Triggers
|
|
8
|
+
|
|
9
|
+
This skill has no auto-injection triggers. It is **invoke-only**: it is loaded on demand
|
|
10
|
+
via the `invoke_skill` tool, normally by the [`bitbucket`](../bitbucket/) hub skill after
|
|
11
|
+
it detects a Bitbucket Data Center environment (i.e. `BITBUCKET_DATA_CENTER_TOKEN` is set).
|
|
12
|
+
|
|
13
|
+
## Details
|
|
14
|
+
|
|
15
|
+
See [`SKILL.md`](SKILL.md) for the full content, including authenticated `scm/` git remote
|
|
16
|
+
construction and pull request instructions. Note the key differences from Bitbucket Cloud:
|
|
17
|
+
the REST API is version `1.0` under `https://{domain}/rest/api/1.0`, repositories are
|
|
18
|
+
addressed as `PROJECT/repo_slug` (project key), git remotes use the
|
|
19
|
+
`scm/{project}/{repo}.git` path, and pull requests are opened with
|
|
20
|
+
`create_bitbucket_data_center_pr`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bitbucket-data-center
|
|
3
|
+
description: Bitbucket Data Center (self-hosted Bitbucket Server) specifics — authenticate with BITBUCKET_DATA_CENTER_TOKEN, use the REST API 1.0, PROJECT/repo_slug repositories, scm/ git remotes, and the create_bitbucket_data_center_pr tool. Loaded on demand by the bitbucket skill once a Data Center environment is detected.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are working with **Bitbucket Data Center** (self-hosted Bitbucket Server). You have
|
|
7
|
+
access to an environment variable, `BITBUCKET_DATA_CENTER_TOKEN`, which contains a basic
|
|
8
|
+
auth token in the format `username:your-token` that allows you to interact with the git
|
|
9
|
+
repository and the REST API.
|
|
10
|
+
|
|
11
|
+
> Environment variable names are case-sensitive. If `BITBUCKET_DATA_CENTER_TOKEN` is not
|
|
12
|
+
> present, use whichever case variant actually exists (for example
|
|
13
|
+
> `bitbucket_data_center_token`). Run `env | grep -i 'bitbucket_data_center'` to find it.
|
|
14
|
+
|
|
15
|
+
- REST API base URL: `https://{domain}/rest/api/1.0`
|
|
16
|
+
- Repository identifier format: `PROJECT/repo_slug` (project key, slash, repo slug)
|
|
17
|
+
|
|
18
|
+
You can use this token to interact with the Bitbucket Data Center REST API:
|
|
19
|
+
```bash
|
|
20
|
+
curl -u "${BITBUCKET_DATA_CENTER_TOKEN}" https://{domain}/rest/api/1.0/...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
<IMPORTANT>
|
|
24
|
+
ALWAYS use the Bitbucket Data Center API for operations instead of a web browser.
|
|
25
|
+
ALWAYS use the `create_bitbucket_data_center_pr` tool to open a pull request
|
|
26
|
+
</IMPORTANT>
|
|
27
|
+
|
|
28
|
+
If you encounter authentication issues when pushing to Bitbucket Data Center (such as password prompts or permission errors), the old token may have expired. In such case, update the remote URL to include the current token: `git remote set-url origin https://${BITBUCKET_DATA_CENTER_TOKEN}@{domain}/scm/{project_lower}/{repo}.git`
|
|
29
|
+
|
|
30
|
+
The token is a `username:token` pair, so if the username or token contains characters that are reserved in URLs (such as `@`), split on the first `:` and URL-encode each part before embedding it in a remote:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
BB_USER="${BITBUCKET_DATA_CENTER_TOKEN%%:*}" && \
|
|
34
|
+
BB_PASS="${BITBUCKET_DATA_CENTER_TOKEN#*:}" && \
|
|
35
|
+
ENCODED_USER=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$BB_USER") && \
|
|
36
|
+
ENCODED_PASS=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$BB_PASS") && \
|
|
37
|
+
git remote set-url origin "https://${ENCODED_USER}:${ENCODED_PASS}@{domain}/scm/{project_lower}/{repo}.git"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Here are some instructions for pushing, but ONLY do this if the user asks you to:
|
|
41
|
+
* NEVER push directly to the `main` or `master` branch
|
|
42
|
+
* Git config (username and email) is pre-set. Do not modify.
|
|
43
|
+
* You may already be on a branch starting with `openhands-workspace`. Create a new branch with a better name before pushing.
|
|
44
|
+
* Use the `create_bitbucket_data_center_pr` tool to create a pull request, if you haven't already
|
|
45
|
+
* Once you've created your own branch or a pull request, continue to update it. Do NOT create a new one unless you are explicitly asked to. Update the PR title and description as necessary, but don't change the branch name.
|
|
46
|
+
* Use the main branch as the base branch, unless the user requests otherwise
|
|
47
|
+
* After opening or updating a pull request, send the user a short message with a link to the pull request.
|
|
48
|
+
* Do NOT mark a pull request as ready to review unless the user explicitly says so
|
|
49
|
+
* Do all of the above in as few steps as possible. E.g. you could push changes with one step by running the following bash commands:
|
|
50
|
+
```bash
|
|
51
|
+
git remote -v && git branch # to find the current org, repo and branch
|
|
52
|
+
git checkout -b create-widget && git add . && git commit -m "Create widget" && git push -u origin create-widget
|
|
53
|
+
```
|
|
@@ -115,7 +115,7 @@ Require:
|
|
|
115
115
|
8. **Dependency Changes**
|
|
116
116
|
If dependency lock changes have downgraded a dependency, comment pointing that out to make sure it was intentional.
|
|
117
117
|
|
|
118
|
-
When a PR adds a new dependency or bumps an existing one, review the upstream release for supply chain risk. If any target version was published less than 7 days ago, do **NOT** approve the PR yet — leave a blocking review comment and wait until the version is at least 7 days old. Read `references/supply-chain-security.md` for the full verification checklist including risk-based scrutiny tiers, concrete commands for checking release provenance, and escalation guidance.
|
|
118
|
+
When a PR adds a new dependency or bumps an existing one, review the upstream release for supply chain risk. If any target version was published less than 7 days ago, do **NOT** approve the PR yet — leave a blocking review comment and wait until the version is at least 7 days old. First-party packages maintained by the same organization as the reviewed repository are intentionally excluded from the 7-day waiting rule, but still scrutinize them for supply-chain risk using the checklist. Read `references/supply-chain-security.md` for the full verification checklist including risk-based scrutiny tiers, concrete commands for checking release provenance, and escalation guidance.
|
|
119
119
|
|
|
120
120
|
9. **Risk and Safety Evaluation**
|
|
121
121
|
Read `references/risk-evaluation.md` for the full risk evaluation framework including risk levels (🟢 Low / 🟡 Medium / 🔴 High), risk factors, escalation guidance, and repo-specific risk rules.
|
|
@@ -7,7 +7,7 @@ When a PR adds a new dependency or bumps an existing one, review the upstream re
|
|
|
7
7
|
Release recency is the primary risk signal - even widely-used, established packages can be compromised (e.g., LiteLLM was a popular package with high download counts when it was hijacked). Check when the target version was published before choosing a tier.
|
|
8
8
|
|
|
9
9
|
**Apply full scrutiny** (all checks below) when:
|
|
10
|
-
- The target version was published less than 7 days ago - regardless of package popularity or age. For PyPI: visit `https://pypi.org/project/<package>/<version>/` and check the "Released" date. For npm: run `npm view <package>@<version> time`. Recent releases have not had time for community vetting, and this is exactly the window supply chain attackers exploit.
|
|
10
|
+
- The target version was published less than 7 days ago - regardless of package popularity or age, except first-party packages maintained by the same organization as the reviewed repository. First-party packages are intentionally excluded from the 7-day waiting rule: do not block solely on freshness, but still scrutinize them for supply-chain risk using this checklist. For PyPI: visit `https://pypi.org/project/<package>/<version>/` and check the "Released" date. For npm: run `npm view <package>@<version> time`. Recent releases have not had time for community vetting, and this is exactly the window supply chain attackers exploit.
|
|
11
11
|
- Adding a dependency not previously used in this project
|
|
12
12
|
- Upgrading a package that was first published less than 6 months ago (check oldest version at `https://pypi.org/project/<package>/#history` or `npm view <package> time | head -3`) or has low weekly downloads (for PyPI: check `https://pypistats.org/packages/<package>` for weekly downloads; for npm: see weekly downloads on the package page at `https://www.npmjs.com/package/<package>`; use <10k on PyPI / <1k on npm as thresholds)
|
|
13
13
|
- The dependency includes native code, install hooks, or system-level access
|
|
@@ -28,4 +28,4 @@ Release recency is the primary risk signal - even widely-used, established packa
|
|
|
28
28
|
|
|
29
29
|
## Escalation Guidance
|
|
30
30
|
|
|
31
|
-
Escalate to 🔴 High Risk if any high-severity signal is present: yanked/retracted versions, source-to-package divergence, or new install-time behavior (post-install scripts, `.pth` files). For medium-severity signals (brand-new release with no adoption signal, missing release notes), escalate only when combined with other signals from this checklist (medium or high severity) or when the package is under full scrutiny. If a dependency is under full scrutiny solely because the target version is newer than 7 days, do **NOT** approve until it is at least 7 days old; after that, re-evaluate it using the rest of this checklist. For dependencies under standard scrutiny, brand-new publication alone is not sufficient to escalate - established packages with frequent release cycles routinely publish new versions.
|
|
31
|
+
Escalate to 🔴 High Risk if any high-severity signal is present: yanked/retracted versions, source-to-package divergence, or new install-time behavior (post-install scripts, `.pth` files). For medium-severity signals (brand-new release with no adoption signal, missing release notes), escalate only when combined with other signals from this checklist (medium or high severity) or when the package is under full scrutiny. If a dependency is under full scrutiny solely because the target version is newer than 7 days, do **NOT** approve until it is at least 7 days old unless it is first-party; after that, re-evaluate it using the rest of this checklist. For first-party packages, do not block solely on freshness, but still document the supply-chain risk review. For dependencies under standard scrutiny, brand-new publication alone is not sufficient to escalate - established packages with frequent release cycles routinely publish new versions.
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
# State
|
|
1
|
+
# State Schema
|
|
2
2
|
|
|
3
|
-
The automation maintains a JSON state
|
|
3
|
+
The automation maintains a JSON state document that persists across polling runs.
|
|
4
4
|
It is the source of truth for which trigger-label events have queued reviews
|
|
5
5
|
and which conversations are still active.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Storage
|
|
10
|
+
|
|
11
|
+
**Primary (cloud):** The state is stored in the automation service's built-in KV
|
|
12
|
+
store under the key `"state"`. The KV store is available when `AUTOMATION_KV_TOKEN`
|
|
13
|
+
is injected into the run environment. Each automation has its own isolated namespace.
|
|
14
|
+
|
|
15
|
+
**Fallback (local/dev):** When the KV store is not available, the state is written
|
|
16
|
+
to a local JSON file at:
|
|
10
17
|
|
|
11
18
|
```
|
|
12
19
|
{WORKSPACE_BASE_ROOT}/automation-state/github_pr_reviewer_label_event_{automation_id}.json
|
|
@@ -116,8 +123,15 @@ Trigger label applied on GitHub
|
|
|
116
123
|
## Resetting State
|
|
117
124
|
|
|
118
125
|
To force the automation to reconsider previous label events, delete the state
|
|
119
|
-
file
|
|
126
|
+
from the KV store (cloud) or the fallback file (local).
|
|
127
|
+
|
|
128
|
+
**Cloud (KV store):**
|
|
129
|
+
```bash
|
|
130
|
+
curl -X DELETE "${OPENHANDS_HOST}/api/automation/v1/kv/state" \
|
|
131
|
+
-H "Authorization: Bearer ${AUTOMATION_KV_TOKEN}"
|
|
132
|
+
```
|
|
120
133
|
|
|
134
|
+
**Local (file fallback):**
|
|
121
135
|
```bash
|
|
122
136
|
rm ~/.openhands/workspaces/automation-state/github_pr_reviewer_label_event_<id>.json
|
|
123
137
|
```
|