Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,19 @@
"cloud-native"
]
},
{
"name": "adapt-yourself",
"source": "./adapt-yourself",
"description": "Decide how to make OpenHands adapt/improve itself persistently: skills, AGENTS.md, hooks, plugins, MCP servers, or code changes in OpenHands-CLI and software-agent-sdk.",
"category": "development",
"keywords": [
"openhands",
"customization",
"skills",
"hooks",
"plugins"
]
},
{
"name": "notion",
"source": "./notion",
Expand Down
8 changes: 8 additions & 0 deletions skills/adapt-yourself/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# adapt-yourself

This skill is a playbook for “self-modification” requests:

- deciding whether the user actually needs code changes, vs.
- adding a repo/user skill, always-on repo instructions (`AGENTS.md`), hooks (`.openhands/hooks.json`), plugins, or MCP tooling.

The canonical instructions live in [`SKILL.md`](SKILL.md).
152 changes: 152 additions & 0 deletions skills/adapt-yourself/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
name: adapt-yourself
description: Decide how to make OpenHands adapt/improve itself persistently (after restart) by choosing between repo/user skills, always-on instructions, hooks, plugins, MCP servers, or code changes in OpenHands-CLI and software-agent-sdk. Includes uv + uv tool workflows and restart/reload behavior.
triggers:
- modify yourself
- change your behavior
- self-modify
- adapt yourself
- self modification
- hack openhands
- .agents/skills
- hooks.json
- plugin.json
---

# Modify OpenHands (self-modification playbook)

When a user says things like “modify yourself to do X” or “remember this next time”, **don’t jump to editing Python code**.
OpenHands has multiple extensibility layers; choose the *smallest*, *safest*, and *most persistent* mechanism that matches the user’s intent.

This skill is about **persistent** changes that should still apply after the user reloads or restarts the CLI / app. If the user wants behavior only for the current conversation, you don't need the mechanisms in this skill—just follow their instructions directly in this session.

## 0) First: clarify what kind of change the user wants

Clarify the **scope** and **type** of the change (skip questions the user already answered):

1. **Persistence scope**: Should this change apply…
- for this *repository/workspace*?
- for *all repos on this machine* (user-global)?
- for *everyone* (contribution upstream / extensions registry)?
2. **Change type**: Is it primarily…
- instructions/workflow (“when I ask for X, do Y”)?
- a safety/policy constraint (“never run rm -rf”, “ask before network calls”)?
- a new capability/tool integration (GitHub, Jira, internal APIs, etc.)?
- a bug fix / UI change in the CLI or SDK?
3. **Where do they run OpenHands?**
- `uv tool install openhands` (tool environment)
- from a local clone (developer workflow)
- via a remote runtime / server

Then follow the decision tree below.

## 1) Prefer non-code extensibility (often enough)

### 1.1 Write a skill (AgentSkills / progressive disclosure)

Use when the user wants repeatable expertise/workflows, e.g.:
- “When I say ‘release notes’, use this structure”
- “Here’s how we do migrations in our company”
- “Read the Daytona docs and learn how to use it”

**Where to put it (in priority order):**

1. **Project-local (recommended):** `<repo>/.agents/skills/<skill-name>/SKILL.md`
2. **User-global:** `~/.agents/skills/<skill-name>/SKILL.md`

Notes:
- **Project skills override user + public skills** (same `name`). This is the simplest way to “patch” a public skill locally.
- Add `triggers:` only when you really want automatic activation; prefer **distinctive phrases** to avoid injecting the skill on unrelated messages.

See: [Templates](references/TEMPLATES.md#agentskillsskillmd-template).

### 1.2 Add always-on repo instructions (AGENTS.md)

Use when the user wants **always-applied** guidance for a repository (style, commands, guardrails, conventions):

- Create or edit `<repo>/AGENTS.md` (or model-specific variants like `CLAUDE.md`, `GEMINI.md` if your environment supports them).
- Put the repo rules there.

This gets loaded at conversation start as “always-on context” (not progressive disclosure).

### 1.3 Add hooks (policy/automation) via `.openhands/hooks.json`

Use when the user wants **enforcement** or **automation** around tool usage, e.g.:
- “Before any git commit, run tests.”
- “Block any command that tries to access prod without approval.”
- “Reject tool calls that write outside the repo.”

Hooks are executed on lifecycle events (like `pre_tool_use`) and can **allow / block / modify** actions.

See: [Hook templates](references/TEMPLATES.md#hookshooksjson-template) and [Hook architecture notes](references/ARCHITECTURE.md#hooks).

### 1.4 Add tools via MCP (`.mcp.json`)

Recommend MCP **only when there is a concrete MCP server to add**:

- The user explicitly asks to “add an MCP server”, **or**
- The user asks for a capability and you can point to an existing MCP server for it (e.g., from that project’s docs / an official MCP server repo).

If there isn’t an MCP server available for what they want, don’t force MCP:
- start with a **skill** (instructions/workflow), or
- if they truly need a new tool, the real work item is to **build or install an MCP server** (or implement a native tool/code change).

MCP server configuration location **depends on the runtime**:

- **OpenHands-CLI** persists MCP servers in `~/.openhands/mcp.json` (or `$OPENHANDS_PERSISTENCE_DIR/mcp.json`).
- **Software Agent SDK skills/plugins** use a **per-skill/per-plugin** `.mcp.json` file located inside the skill/plugin directory.

See: [MCP template](references/TEMPLATES.md#mcp-template).

### 1.5 Package it as a plugin (shareable bundle)

Use when the change should be **portable** across repos or shared with others, and it includes more than just instructions:
- skills + hooks + MCP config together
- optional slash commands and/or specialized agents

Plugins follow the Claude Code-compatible structure, with `.plugin/plugin.json` (or `.claude-plugin/plugin.json`).

See: [Plugin template](references/TEMPLATES.md#plugin-template) and [Plugin architecture notes](references/ARCHITECTURE.md#plugins).

## 2) When code changes are actually required

Choose the correct codebase / package:

- **CLI UX, TUI widgets, slash commands, config files** → `OpenHands/OpenHands-CLI`
- **Agent runtime logic, skill loading, hooks system, plugin loader, event model** → `OpenHands/software-agent-sdk` → `openhands-sdk`
- **Built-in tools (Terminal, File Editor, Task Tracker, etc.)** → `OpenHands/software-agent-sdk` → `openhands-tools`
- **Workspace mounting / file sync / workspace abstraction** → `OpenHands/software-agent-sdk` → `openhands-workspace`

If you’re not sure, start by reproducing the issue and locating the code path.

## 3) uv development workflows (including `uv tool install openhands`)

- If they run OpenHands from a **local clone**: use `uv sync` + `uv run openhands`.
- If they installed OpenHands via **`uv tool install openhands`**:
- safest: `uv tool run --from /path/to/OpenHands-CLI openhands`
- persistent: `uv tool install --force --editable /path/to/OpenHands-CLI`
- If they need to modify the **SDK** while running the CLI, remember: the CLI often **pins exact SDK/tool versions**. Prefer aligning versions; use overrides only for local development.

Details: [Installation modes (`uv tool` vs `uv run`)](references/INSTALLATION_MODES.md).

## 4) What requires a restart to take effect?

- **Skills / AGENTS.md**: loaded at conversation start → usually **start a new conversation** to pick them up. Ask the user to fully restart OpenHands only if needed.
- **Hooks (.openhands/hooks.json)**: loaded when the agent/conversation initializes → ask the user to restart (or create a fresh session) to guarantee reload.
- **Plugins**: loaded when the conversation initializes → ask the user to restart (or create a fresh session) to guarantee reload.
- **Editable Python code (uv tool `--editable` or local `uv run`)**: changes apply the next time the Python process starts → ask the user to restart the CLI/app.

## 5) Verification checklist

After making a “self-modification” change, guide the **user** through verification:

1. Ask the user to start a **fresh conversation** (and restart OpenHands only if needed).
2. If they’re using the **OpenHands CLI TUI**, ask them to type `/skills` to confirm the expected skills/hooks/MCPs are loaded.
3. Ask the user to send a tiny, deterministic **test prompt** that should trigger the new behavior.
4. If it’s a code change, run the smallest relevant test suite (or ask the user to run it) and confirm the behavior matches.

## References

- [Architecture: CLI vs SDK vs skills/hooks/plugins](references/ARCHITECTURE.md)
- [Installation modes: `uv tool` vs `uv run` and version pinning](references/INSTALLATION_MODES.md)
- [Templates: SKILL.md, hooks.json, plugin.json, .mcp.json](references/TEMPLATES.md)
101 changes: 101 additions & 0 deletions skills/adapt-yourself/references/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# OpenHands extensibility architecture (CLI + SDK)

OpenHands “behavior” can be modified at multiple layers. The key is to choose the layer that matches the user’s intent.

## Components

### OpenHands CLI (`OpenHands/OpenHands-CLI`)

- Python package name: `openhands`
- Entry points: `openhands`, `openhands-acp`
- Responsibilities:
- Terminal UI (Textual)
- Loading config + wiring up an SDK `Agent`
- Choosing tools and building an `AgentContext`

In the CLI codebase, look for where it creates the `AgentContext` and enables:
- project skills
- user skills
- public skills

### Software Agent SDK monorepo (`OpenHands/software-agent-sdk`)

This repo is a **uv workspace** that produces multiple packages:

- `openhands-sdk` (module: `openhands.sdk`)
- agent runtime primitives (Agent, Conversation, Event model)
- context loading (skills)
- hooks system
- plugin loader

- `openhands-tools` (module: `openhands.tools`)
- built-in tools used by many OpenHands projects

- `openhands-workspace` (module: `openhands.workspace`)
- workspace mounting, file sync abstractions

- `openhands-agent-server`
- server-side runtime

## Skills

Skills are loaded from multiple locations; **project-local skills override user + public**.

Common locations:

- Project-local:
- `<repo>/.agents/skills/`

- User-global:
- `~/.agents/skills/`

- Public registry:
- `https://github.com/OpenHands/extensions` (cached locally under `~/.openhands/skills-cache/`)

Skill types:

- **AgentSkills format**: a directory with `SKILL.md` (progressive disclosure)
- **Always-on instructions**: repo instruction files like `AGENTS.md` (loaded at conversation start)

## Hooks

Hooks are configured via JSON and executed on events (e.g. `pre_tool_use`).

Typical locations (depending on project / SDK config):

- `<repo>/.openhands/hooks.json`
- `~/.openhands/hooks.json`

Hook scripts receive an event payload on stdin as JSON and respond with a decision.

## Plugins

Plugins are bundles of:

- skills
- hooks
- MCP config
- optional commands and agents

They follow the Claude Code-compatible directory structure:

```
my-plugin/
├── .plugin/
│ └── plugin.json
├── skills/
├── hooks/
│ └── hooks.json
├── .mcp.json
└── README.md
```

Plugins can be:
- loaded from a local path
- fetched from GitHub/git URLs and cached under `~/.openhands/cache/plugins/`

## MCP servers (tools)

MCP servers provide tool endpoints to the agent.

They are configured via `.mcp.json` (location depends on host project). Plugins can also provide MCP config.
114 changes: 114 additions & 0 deletions skills/adapt-yourself/references/INSTALLATION_MODES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Installation and development modes (uv)

This reference is for making “persistent self-modifications” that apply after restart.

## `uv run` (project environment) mode

Use when you are developing from a git clone.

- `uv sync` installs dependencies into a project-local `.venv/` (and/or uses the uv lockfile).
- `uv run ...` runs inside that environment.

Typical CLI dev flow:

```bash
cd OpenHands-CLI
uv sync --group dev
uv run openhands
```

Typical SDK dev flow:

```bash
cd software-agent-sdk
uv sync --group dev
uv run pytest
```

### Pros

- Simple debugging (local sources)
- Easy to run tests + linters
- No global tool replacement needed

### Cons

- You must run `openhands` via `uv run openhands` (or ensure the venv is on PATH)

## `uv tool install openhands` (tool environment) mode

In this mode, `uv` installs the CLI into a dedicated tool environment and exposes a shim executable.

### Inspect installed tools

```bash
uv tool list
uv tool dir
```

If `openhands` is installed and not found on PATH, run:

```bash
uv tool update-shell
```

### Replace the tool with an editable local checkout

This is the most common way to run a modified CLI *after restart*:

```bash
uv tool install --force --editable /path/to/OpenHands-CLI
```

After that, `openhands` should use the editable sources.

### Run a local checkout without installing

This is the safest way to test a change:

```bash
uv tool run --from /path/to/OpenHands-CLI openhands
```

## SDK vs CLI version pins

The CLI often pins exact versions of:

- `openhands-sdk`
- `openhands-tools`
- `openhands-workspace`

If you want to use a local SDK checkout *together with the CLI*, you must handle that pinning.

### What usually works

1. Check the versions the CLI requires:
- `OpenHands-CLI/pyproject.toml`
2. Check out the matching tag/commit in `software-agent-sdk`.
3. Install the matching SDK packages in editable mode into the environment that runs the CLI.

### What commonly fails

Trying to install an SDK checkout at version `X` into an environment where the CLI requires `openhands-sdk==Y`.

### Using `--overrides` for development

As a last resort for local development, you can override pinned deps.

Create a file (e.g. `overrides.txt`) containing a direct URL or local path spec:

```text
openhands-sdk @ file:///absolute/path/to/software-agent-sdk/openhands-sdk
openhands-tools @ file:///absolute/path/to/software-agent-sdk/openhands-tools
openhands-workspace @ file:///absolute/path/to/software-agent-sdk/openhands-workspace
```

Then install the CLI tool using that overrides file:

```bash
uv tool install --force --editable /path/to/OpenHands-CLI --overrides overrides.txt
```

Notes:
- This is intentionally “break glass”; it can produce a mismatched runtime.
- Prefer aligning versions whenever possible.
Loading
Loading