feat: add development and hf-hangman-lab skills

development: absorbed openclaw-plugin-dev as a workflow, with
reference docs for plugin structure, hooks, tools, state, config.

hf-hangman-lab: hf-wakeup workflow — full agent wakeup lifecycle:
set busy → check due slots → select & defer → identify task →
plan work → create work channel → execute. All branches end with
status reset to idle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhi
2026-04-19 13:31:27 +00:00
parent 5a8f490cc2
commit 238574ffd2
14 changed files with 270 additions and 133 deletions

12
development/SKILL.md Normal file
View File

@@ -0,0 +1,12 @@
---
name: development
description: Software development workflows — plugin development, code review, and implementation patterns. Use when building OpenClaw plugins, implementing features, or following development processes.
---
## Workflows
- `{baseDir}/workflows/openclaw-plugin-development.md` — When creating or modifying OpenClaw plugins. Covers project structure, entry points, hooks, tools, state management, config, and debugging.
## Reference
- `{baseDir}/docs/` — Plugin development reference docs (structure, hooks, tools, state, config, debugging).

View File

@@ -0,0 +1,128 @@
# OpenClaw Plugin Development
When creating or modifying an OpenClaw plugin.
> Reference docs in `{baseDir}/docs/` cover each topic in detail.
## Process
### 1. Scaffold
Create the project structure:
```
my-plugin/
plugin/
index.ts # export default { id, name, register }
openclaw.plugin.json # config schema (additionalProperties: false)
package.json # name, version, type: module
hooks/ # one file per hook handler
tools/ # tool registrations
core/ # pure logic (no plugin-sdk imports)
scripts/
install.mjs # --install / --uninstall
package.json # dev dependencies
tsconfig.plugin.json
.gitignore
```
See `{baseDir}/docs/structure.md` for conventions.
### 2. Entry Point
Follow the globalThis lifecycle pattern:
```typescript
const _G = globalThis as Record<string, unknown>;
const LIFECYCLE_KEY = "_myPluginLifecycleRegistered";
export default {
id: "my-plugin",
name: "My Plugin",
register(api) {
if (!_G[LIFECYCLE_KEY]) {
_G[LIFECYCLE_KEY] = true;
// gateway-level init (once)
api.on("gateway_stop", () => { _G[LIFECYCLE_KEY] = false; });
}
// agent-level hooks (every register call, dedup inside)
registerMyHook(api);
registerMyTools(api);
},
};
```
See `{baseDir}/docs/entry-point.md` for details.
### 3. Hooks
Each hook in its own file under `hooks/`. Must use dedup on globalThis:
- `before_model_resolve`, `before_prompt_build` → WeakSet on event object
- `agent_end` → Set on runId with size cap 500
- `gateway_start/stop` → globalThis flag
If returning `prependSystemContext`/`appendSystemContext`, set `allowPromptInjection: true` in config.
See `{baseDir}/docs/hooks.md`.
### 4. Tools
Interface is `inputSchema` + `execute` (not `parameters` + `handler`):
```typescript
api.registerTool({
name: "my-tool",
inputSchema: { type: "object", properties: { ... }, required: [...] },
execute: async (toolCallId, params) => { return { result: "ok" }; },
});
```
For agent context access, use factory form: `api.registerTool((ctx) => ({ ... }))`.
See `{baseDir}/docs/tools.md`.
### 5. State Management
All mutable state on `globalThis`, not module-level variables (hot reload resets modules).
- Business state, dedup sets, lifecycle flags → `globalThis`
- Cross-plugin API → `globalThis.__pluginId`
- Pure functions → module-level is fine
See `{baseDir}/docs/state.md`.
### 6. Config Schema
`openclaw.plugin.json` must have `additionalProperties: false`. Every config field in install script must exist in schema. Never set sensitive fields (tokens) in install script.
See `{baseDir}/docs/config.md`.
### 7. Install Script
```bash
node scripts/install.mjs --install # build, copy to ~/.openclaw/plugins/<id>, update config
node scripts/install.mjs --uninstall # remove from config and filesystem
```
See `{baseDir}/docs/config.md`.
### 8. Build & Test
```bash
npm run build
node scripts/install.mjs --install
openclaw gateway restart
openclaw logs --follow
```
### 9. Checklist Before Deploy
- [ ] Hook handlers have dedup on globalThis
- [ ] Gateway lifecycle protected by globalThis flag
- [ ] Business state on globalThis
- [ ] Schema matches actual config fields
- [ ] Install script uses setIfMissing, no sensitive fields
- [ ] Clean dist before copy (`rmSync`)
See `{baseDir}/docs/debugging.md` for full checklist.

8
hf-hangman-lab/SKILL.md Normal file
View File

@@ -0,0 +1,8 @@
---
name: hf-hangman-lab
description: HarborForge integration workflows — wakeup handling, task execution, and calendar management. Use when woken up by the HF calendar scheduler or interacting with HarborForge.
---
## Workflows
- `{baseDir}/workflows/hf-wakeup.md` — When woken up by the HF calendar scheduler with due slots. Handles status transitions, slot selection, task identification, and work channel creation.

View File

@@ -0,0 +1,122 @@
# HF Wakeup
When you are woken up by the HF calendar scheduler because you have due slots.
> **Safety rule**: If you encounter any unexpected error or exit this workflow early for any reason, set your HF status back to idle before stopping.
## Process
### 0. Set Status Busy
Immediately set your HF status to busy:
```bash
hf agent status --set busy
```
### 1. Check Due Slots
Query your today's calendar for due slots:
```bash
hf calendar show --date today --status not-started,deferred
```
Review the returned slots. Note which ones are due (scheduled_at <= now).
### 2. Select Slot & Defer Others
Choose which slot to start working on (consider priority and your judgment).
For remaining due slots that you won't handle now, defer them to a later time:
```bash
hf calendar slot update --id <slot_id> --status deferred --time HH:MM
```
### 3. Identify the Work
Determine what to do based on the selected slot:
#### 3.1 Check Slot for Task Reference
Look at the slot's `event_data` — does it contain an HF task reference (task code or task ID)?
If yes → go to step 4 with that task.
#### 3.2 Check Notes/Memory
If no task reference in the slot, check your notes (`memory/YYYY-MM-DD.md`) and memory for any planned work for this time slot.
If you find planned work → go to step 4 with that work.
#### 3.3 Find Available Tasks
If no planned work found:
1. Check HF for tasks assigned to you:
```bash
hf tasks list --assignee me --status open
```
2. If none assigned, look for unassigned tasks you can take:
```bash
hf tasks list --status open --unassigned
```
3. If no tasks available at all:
- Set your status to on-call:
```bash
hf agent status --set on_call
```
- Mark the slot as finished:
```bash
hf calendar slot update --id <slot_id> --status finished
```
- Done. You will be available to respond to incoming requests.
### 4. Plan the Work
Read the HF task description and understand what needs to be done.
Search for relevant skill workflows that may help with execution:
- Code implementation → check `development` skill
- Deployment → check operator-specific workflows
- Skill creation/maintenance → check `claw-skills` skill
- Other → use your judgment and available tools
Write a detailed plan covering:
- Steps to complete the task
- Tools and resources needed
- Any discussions or collaborations required
- Estimated time
**Every branch of your plan must end with setting your HF status back to idle:**
```bash
hf agent status --set idle
```
### 5. Create Work Channel & Start
Create a work channel to execute your plan:
```bash
# For independent work:
create-work-channel --name "<task-code>-work" --guild-id <guild_id>
# For collaborative work requiring discussion:
create-discussion-channel --name "<topic>" --participants <discord_ids> --discussion-guide-path <path_to_plan>
```
Send your plan to the work channel so you can follow it during execution.
### 6. Error Recovery
If anything goes wrong at any point in this workflow:
```bash
hf agent status --set idle
```
This ensures you don't get stuck in a busy state preventing future wakeups.

View File

@@ -1,21 +0,0 @@
---
name: openclaw-plugin-dev
description: OpenClaw plugin development — structure, conventions, hooks, tools, install scripts, and debugging. Use when creating, modifying, or debugging OpenClaw plugins.
---
> Reference docs provide the full specification. Workflows guide specific tasks.
## Reference
- `{baseDir}/docs/structure.md` — Project layout, directory conventions, file naming
- `{baseDir}/docs/entry-point.md` — Plugin entry format, globalThis patterns, lifecycle protection
- `{baseDir}/docs/hooks.md` — Hook registration, dedup patterns, available hooks
- `{baseDir}/docs/tools.md` — Tool registration interface (inputSchema + execute)
- `{baseDir}/docs/state.md` — State management rules (globalThis vs module-level)
- `{baseDir}/docs/config.md` — Config schema, install scripts, sensitive fields
- `{baseDir}/docs/debugging.md` — Dev loop, log keywords, smoke testing
## Workflows
- `{baseDir}/workflows/create-plugin.md` — When creating a new OpenClaw plugin from scratch.
- `{baseDir}/workflows/add-hook.md` — When adding a new hook handler to an existing plugin.

View File

@@ -1,40 +0,0 @@
# Add Hook
When adding a new hook handler to an existing plugin.
> See `{baseDir}/docs/hooks.md` for available hooks and dedup patterns.
## Process
### 1. Create Hook File
Add `plugin/hooks/<hook-name>.ts`. Export a registration function:
```typescript
export function registerMyHook(api, config) {
// Set up dedup on globalThis
// api.on("<hook-name>", handler)
}
```
### 2. Add Dedup
Choose the right dedup pattern:
- `before_model_resolve`, `before_prompt_build` → WeakSet on event object
- `agent_end` → Set on runId with size cap (500)
- `gateway_start/stop` → globalThis flag (in index.ts, not in hook file)
### 3. Register in index.ts
Import and call the registration function in the `register()` method.
Hooks that need to run every register() call (agent-scoped): put outside the lifecycle guard.
Hooks that should run once (gateway-scoped): put inside the lifecycle guard.
### 4. If Prompt Injection
If the hook returns `prependSystemContext` or `appendSystemContext`, ensure `allowPromptInjection: true` is set in the plugin's config entry and in the install script.
### 5. Test
Reinstall, restart gateway, verify via logs.

View File

@@ -1,72 +0,0 @@
# Create Plugin
When creating a new OpenClaw plugin from scratch.
> See `{baseDir}/docs/structure.md` for directory layout and conventions.
## Process
### 1. Scaffold
Create the project structure:
```
my-plugin/
plugin/
index.ts
openclaw.plugin.json
package.json
core/
hooks/
tools/
scripts/
install.mjs
routers/ # if applicable
package.json # dev dependencies (typescript, @types/node)
tsconfig.plugin.json
.gitignore
```
### 2. Define Config Schema
Write `plugin/openclaw.plugin.json` with `additionalProperties: false`. Only include fields the plugin actually uses.
### 3. Implement Entry Point
Follow the pattern in `{baseDir}/docs/entry-point.md`:
- `export default { id, name, register }`
- globalThis lifecycle protection
- Hooks in separate files under `hooks/`
- Tools in separate files under `tools/`
- Business logic in `core/` (no plugin-sdk imports)
### 4. Implement Hooks
Follow dedup patterns in `{baseDir}/docs/hooks.md`. Each hook gets its own file.
### 5. Implement Tools
Follow the interface in `{baseDir}/docs/tools.md`: `inputSchema` + `execute`.
### 6. Write Install Script
Follow `{baseDir}/docs/config.md` for install/uninstall conventions.
### 7. Build & Test
```bash
npm run build
node scripts/install.mjs --install
openclaw gateway restart
# Test via Discord or openclaw agent CLI
```
### 8. Push
Create a git repository and push:
```bash
git-ctrl repo create <plugin-name>
git add -A && git commit -m "init: <plugin-name>"
git push -u origin main
```