mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
feat(skills): add debugger diagram and spike skills
# Conflicts: # CHANGELOG.md
This commit is contained in:
@@ -8,6 +8,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
|
|
||||||
- Skills: add a meme-maker skill for curated template search, local SVG/PNG rendering, Imgflip hosted rendering, and Know Your Meme provenance links.
|
- Skills: add a meme-maker skill for curated template search, local SVG/PNG rendering, Imgflip hosted rendering, and Know Your Meme provenance links.
|
||||||
- Agents/tools: shorten built-in tool descriptions and schema hints across media, messaging, sessions, cron, Gateway, web, image/PDF, TTS, nodes, and plan tools while preserving routing guardrails.
|
- Agents/tools: shorten built-in tool descriptions and schema hints across media, messaging, sessions, cron, Gateway, web, image/PDF, TTS, nodes, and plan tools while preserving routing guardrails.
|
||||||
|
- Skills: add node inspector debugging, fused diagram generation, and throwaway spike workflow skills.
|
||||||
- Proxy: support HTTPS managed forward-proxy endpoints and scoped `proxy.tls.caFile` CA trust for proxy endpoint TLS. (#79171) Thanks @jesse-merhi.
|
- Proxy: support HTTPS managed forward-proxy endpoints and scoped `proxy.tls.caFile` CA trust for proxy endpoint TLS. (#79171) Thanks @jesse-merhi.
|
||||||
- QA-Lab: add first-hour 20-turn and optional 100-turn runtime parity scenarios, with tier metadata for standard and soak QA gates. (#80323) Thanks @100yenadmin.
|
- QA-Lab: add first-hour 20-turn and optional 100-turn runtime parity scenarios, with tier metadata for standard and soak QA gates. (#80323) Thanks @100yenadmin.
|
||||||
- QA-Lab: add a live-only Codex Pi-shaped Read vocabulary canary so runtime parity catches native workspace-read prompt compatibility drift. (#80323) Thanks @100yenadmin.
|
- QA-Lab: add a live-only Codex Pi-shaped Read vocabulary canary so runtime parity catches native workspace-read prompt compatibility drift. (#80323) Thanks @100yenadmin.
|
||||||
|
|||||||
53
skills/diagram-maker/SKILL.md
Normal file
53
skills/diagram-maker/SKILL.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
name: diagram-maker
|
||||||
|
description: Create SVG/HTML or Excalidraw diagrams for concepts, architecture, flows, and whiteboards.
|
||||||
|
metadata: { "openclaw": { "emoji": "🧭" } }
|
||||||
|
---
|
||||||
|
|
||||||
|
# Diagram Maker
|
||||||
|
|
||||||
|
Create diagrams as artifacts, not prose. Choose one output mode:
|
||||||
|
|
||||||
|
- `clean-svg`: educational concepts, physical systems, processes, lifecycle, simple data flow.
|
||||||
|
- `architecture-svg`: software/cloud/infra topology, services, databases, queues, trust zones.
|
||||||
|
- `excalidraw`: editable hand-drawn whiteboard, flowchart, sequence, architecture sketch.
|
||||||
|
|
||||||
|
Routing
|
||||||
|
|
||||||
|
- User wants editable/collaborative: choose Excalidraw.
|
||||||
|
- User wants polished standalone browser output: choose SVG/HTML.
|
||||||
|
- Software architecture with infra components: choose architecture SVG.
|
||||||
|
- Science, product, process, concept map, physical object: choose clean SVG.
|
||||||
|
- Unsure: ask one short question only if output format matters; otherwise choose clean SVG.
|
||||||
|
|
||||||
|
Workflow
|
||||||
|
|
||||||
|
1. Extract nodes, groups, labels, and directed relationships.
|
||||||
|
2. Pick layout first: left-to-right, top-down, hub-spoke, swimlanes, layered stack, sequence.
|
||||||
|
3. Keep labels short. Prefer 5-9 main elements over dense diagrams.
|
||||||
|
4. Generate the file at the requested path, or `./diagram.html` / `./diagram.excalidraw`.
|
||||||
|
5. Verify syntax by opening/parsing when feasible.
|
||||||
|
|
||||||
|
SVG/HTML rules
|
||||||
|
|
||||||
|
- Single standalone `.html` file with inline CSS and inline SVG.
|
||||||
|
- No external fonts, JS, images, gradients, glows, decorative blobs, or remote assets.
|
||||||
|
- Use semantic colors, not rainbow sequences: neutral, input, process, storage, external, risk.
|
||||||
|
- Draw connectors before nodes so arrows sit behind boxes.
|
||||||
|
- Every connector path has `fill="none"` and a marker arrow when directed.
|
||||||
|
- Leave 24px text padding inside boxes; do not let text touch borders.
|
||||||
|
- Legend only when symbols/colors are not obvious.
|
||||||
|
|
||||||
|
SVG template
|
||||||
|
|
||||||
|
Use `references/svg-template.md` as the wrapper and replace `<!-- SVG -->`.
|
||||||
|
|
||||||
|
Excalidraw rules
|
||||||
|
|
||||||
|
- Save `.excalidraw` JSON with `type`, `version`, `source`, `elements`, and `appState`.
|
||||||
|
- Use bound text for shape labels. Do not use a nonstandard `label` property.
|
||||||
|
- Keep bound text immediately after its container in the elements array.
|
||||||
|
- Minimum labeled shape: 120x60. Minimum body text: 16px.
|
||||||
|
- Use roughness `1`, `fontFamily: 1`, and simple fills.
|
||||||
|
|
||||||
|
For exact Excalidraw element snippets, read `references/excalidraw-patterns.md`.
|
||||||
85
skills/diagram-maker/references/excalidraw-patterns.md
Normal file
85
skills/diagram-maker/references/excalidraw-patterns.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Excalidraw Patterns
|
||||||
|
|
||||||
|
Envelope:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "excalidraw",
|
||||||
|
"version": 2,
|
||||||
|
"source": "openclaw/diagram-maker",
|
||||||
|
"elements": [],
|
||||||
|
"appState": { "viewBackgroundColor": "#ffffff" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Labeled rounded rectangle:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "rectangle",
|
||||||
|
"id": "svc",
|
||||||
|
"x": 100,
|
||||||
|
"y": 100,
|
||||||
|
"width": 180,
|
||||||
|
"height": 72,
|
||||||
|
"roundness": { "type": 3 },
|
||||||
|
"backgroundColor": "#a5d8ff",
|
||||||
|
"fillStyle": "solid",
|
||||||
|
"strokeWidth": 2,
|
||||||
|
"roughness": 1,
|
||||||
|
"opacity": 100,
|
||||||
|
"boundElements": [{ "id": "svc_text", "type": "text" }]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Bound text:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"id": "svc_text",
|
||||||
|
"x": 112,
|
||||||
|
"y": 124,
|
||||||
|
"width": 156,
|
||||||
|
"height": 24,
|
||||||
|
"text": "API service",
|
||||||
|
"originalText": "API service",
|
||||||
|
"fontSize": 20,
|
||||||
|
"fontFamily": 1,
|
||||||
|
"strokeColor": "#1e1e1e",
|
||||||
|
"textAlign": "center",
|
||||||
|
"verticalAlign": "middle",
|
||||||
|
"containerId": "svc",
|
||||||
|
"autoResize": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Bound arrow:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "arrow",
|
||||||
|
"id": "a1",
|
||||||
|
"x": 280,
|
||||||
|
"y": 136,
|
||||||
|
"width": 140,
|
||||||
|
"height": 0,
|
||||||
|
"points": [
|
||||||
|
[0, 0],
|
||||||
|
[140, 0]
|
||||||
|
],
|
||||||
|
"endArrowhead": "arrow",
|
||||||
|
"startBinding": { "elementId": "svc", "fixedPoint": [1, 0.5] },
|
||||||
|
"endBinding": { "elementId": "db", "fixedPoint": [0, 0.5] }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Palette:
|
||||||
|
|
||||||
|
- Primary/input: `#a5d8ff`
|
||||||
|
- Process: `#d0bfff`
|
||||||
|
- Success/output: `#b2f2bb`
|
||||||
|
- Storage/data: `#c3fae8`
|
||||||
|
- External/warning: `#ffd8a8`
|
||||||
|
- Error/risk: `#ffc9c9`
|
||||||
|
- Note/decision: `#fff3bf`
|
||||||
112
skills/diagram-maker/references/svg-template.md
Normal file
112
skills/diagram-maker/references/svg-template.md
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# SVG HTML Template
|
||||||
|
|
||||||
|
Copy this to a `.html` file and replace `<!-- SVG -->`.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Diagram</title>
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
--bg: #f8fafc;
|
||||||
|
--fg: #172033;
|
||||||
|
--muted: #5b6475;
|
||||||
|
--line: #64748b;
|
||||||
|
--neutral: #e2e8f0;
|
||||||
|
--input: #bfdbfe;
|
||||||
|
--process: #c7d2fe;
|
||||||
|
--storage: #99f6e4;
|
||||||
|
--external: #fde68a;
|
||||||
|
--risk: #fecaca;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--bg: #0f172a;
|
||||||
|
--fg: #e5e7eb;
|
||||||
|
--muted: #a3adbd;
|
||||||
|
--line: #94a3b8;
|
||||||
|
--neutral: #334155;
|
||||||
|
--input: #1d4ed8;
|
||||||
|
--process: #4338ca;
|
||||||
|
--storage: #0f766e;
|
||||||
|
--external: #92400e;
|
||||||
|
--risk: #991b1b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: var(--bg);
|
||||||
|
color: var(--fg);
|
||||||
|
font:
|
||||||
|
14px/1.4 ui-sans-serif,
|
||||||
|
system-ui,
|
||||||
|
-apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
"Segoe UI",
|
||||||
|
sans-serif;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
max-width: 980px;
|
||||||
|
margin: 32px auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 650;
|
||||||
|
fill: var(--fg);
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
fill: var(--fg);
|
||||||
|
}
|
||||||
|
.small {
|
||||||
|
font-size: 12px;
|
||||||
|
fill: var(--muted);
|
||||||
|
}
|
||||||
|
.node {
|
||||||
|
stroke: var(--line);
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
.neutral {
|
||||||
|
fill: var(--neutral);
|
||||||
|
}
|
||||||
|
.input {
|
||||||
|
fill: var(--input);
|
||||||
|
}
|
||||||
|
.process {
|
||||||
|
fill: var(--process);
|
||||||
|
}
|
||||||
|
.storage {
|
||||||
|
fill: var(--storage);
|
||||||
|
}
|
||||||
|
.external {
|
||||||
|
fill: var(--external);
|
||||||
|
}
|
||||||
|
.risk {
|
||||||
|
fill: var(--risk);
|
||||||
|
}
|
||||||
|
.edge {
|
||||||
|
stroke: var(--line);
|
||||||
|
stroke-width: 1.5;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
.zone {
|
||||||
|
fill: none;
|
||||||
|
stroke: var(--line);
|
||||||
|
stroke-width: 1;
|
||||||
|
stroke-dasharray: 6 5;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<main>
|
||||||
|
<!-- SVG -->
|
||||||
|
</main>
|
||||||
|
```
|
||||||
85
skills/node-inspect-debugger/SKILL.md
Normal file
85
skills/node-inspect-debugger/SKILL.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
name: node-inspect-debugger
|
||||||
|
description: Debug Node.js with node inspect, --inspect, breakpoints, CDP, heap, and CPU profiles.
|
||||||
|
metadata: { "openclaw": { "emoji": "🪲", "requires": { "bins": ["node"] } } }
|
||||||
|
---
|
||||||
|
|
||||||
|
# Node Inspect Debugger
|
||||||
|
|
||||||
|
Use when logs are too weak for a Node.js bug: hidden locals, async hangs, flaky tests, child processes, startup races, memory growth, or CPU hot paths.
|
||||||
|
|
||||||
|
Default to `node inspect` first. Use Chrome DevTools Protocol only when you need scripted breakpoints, automated state capture, heap snapshots, or CPU profiles.
|
||||||
|
|
||||||
|
Quick start
|
||||||
|
|
||||||
|
- Pause on entry: `node inspect path/to/script.js`
|
||||||
|
- TypeScript: `node --inspect-brk --import tsx path/to/script.ts`
|
||||||
|
- Existing PID: `kill -SIGUSR1 <pid>` then `node inspect -p <pid>`
|
||||||
|
- Inspect target list: `curl -s http://127.0.0.1:9229/json/list | jq`
|
||||||
|
- OpenClaw CLI path: `node --inspect-brk openclaw.mjs ...`
|
||||||
|
- OpenClaw test path: `OPENCLAW_VITEST_MAX_WORKERS=1 node --inspect-brk scripts/run-vitest.mjs <file>`
|
||||||
|
|
||||||
|
Debugger REPL
|
||||||
|
|
||||||
|
- Continue/step: `cont`, `next`, `step`, `out`, `pause`
|
||||||
|
- Breakpoints: `sb('file.js', 42)`, `sb(42)`, `sb('functionName')`, `breakpoints`, `cb('file.js', 42)`
|
||||||
|
- Inspect: `bt`, `list(8)`, `watch('expr')`, `exec expr`
|
||||||
|
- Current scope: `repl`, then evaluate locals directly; `Ctrl+C` exits repl mode.
|
||||||
|
- Exit safely: `cont` before quitting if the process should continue; otherwise `kill`.
|
||||||
|
|
||||||
|
OpenClaw tips
|
||||||
|
|
||||||
|
- Prefer `127.0.0.1` inspector binds. Do not expose `--inspect=0.0.0.0` unless the network is isolated.
|
||||||
|
- For Vitest, debug one file with one worker. Avoid worker pools while stepping.
|
||||||
|
- For TS source breakpoints, use `--enable-source-maps` when useful; `node inspect` can still show emitted paths.
|
||||||
|
- For child processes, `NODE_OPTIONS=--inspect-brk` can propagate the inspector, but each child needs its own port.
|
||||||
|
- For long-lived gateway or dev processes, attach by PID after confirming the target with `/json/list`.
|
||||||
|
|
||||||
|
Programmatic CDP
|
||||||
|
|
||||||
|
Install tooling outside the repo unless the project already depends on it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /tmp/cdp-tools
|
||||||
|
npm --prefix /tmp/cdp-tools i chrome-remote-interface
|
||||||
|
NODE_PATH=/tmp/cdp-tools/node_modules node /tmp/cdp-debug.cjs
|
||||||
|
```
|
||||||
|
|
||||||
|
Minimal driver:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const CDP = require("chrome-remote-interface");
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const client = await CDP({ port: 9229 });
|
||||||
|
const { Debugger, Runtime } = client;
|
||||||
|
|
||||||
|
Debugger.paused(async ({ callFrames, reason }) => {
|
||||||
|
const top = callFrames[0];
|
||||||
|
console.log("paused", reason, top.url, top.location.lineNumber + 1);
|
||||||
|
const { result } = await Debugger.evaluateOnCallFrame({
|
||||||
|
callFrameId: top.callFrameId,
|
||||||
|
expression: "JSON.stringify({ pid: process.pid })",
|
||||||
|
});
|
||||||
|
console.log(result.value ?? result.description);
|
||||||
|
await Debugger.resume();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Runtime.enable();
|
||||||
|
await Debugger.enable();
|
||||||
|
await Debugger.setBreakpointByUrl({ urlRegex: ".*target\\.js$", lineNumber: 41 });
|
||||||
|
await Runtime.runIfWaitingForDebugger();
|
||||||
|
})();
|
||||||
|
```
|
||||||
|
|
||||||
|
Profiles
|
||||||
|
|
||||||
|
- CPU: enable `Profiler`, `start`, wait, `stop`, write `/tmp/profile.cpuprofile`, open in Chrome DevTools.
|
||||||
|
- Heap: enable `HeapProfiler`, collect `addHeapSnapshotChunk`, call `takeHeapSnapshot`, write `/tmp/heap.heapsnapshot`.
|
||||||
|
|
||||||
|
Pitfalls
|
||||||
|
|
||||||
|
- `--inspect` does not pause; use `--inspect-brk` when setup must happen before code runs.
|
||||||
|
- Default port is `9229`; use `--inspect=0` or a unique port for parallel targets.
|
||||||
|
- If a breakpoint misses, confirm file path, source map behavior, and whether execution already passed the line.
|
||||||
|
- If the process appears frozen after detaching, it may still be paused in the debugger.
|
||||||
51
skills/spike/SKILL.md
Normal file
51
skills/spike/SKILL.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
name: spike
|
||||||
|
description: Run throwaway prototypes to validate feasibility, compare approaches, and report a verdict.
|
||||||
|
metadata: { "openclaw": { "emoji": "🧪" } }
|
||||||
|
---
|
||||||
|
|
||||||
|
# Spike
|
||||||
|
|
||||||
|
Use when the user wants to test an idea before committing to a real build: "spike this", "quick prototype", "is this possible", "compare A/B", "before we build".
|
||||||
|
|
||||||
|
Do not use when reading docs/code can answer the question, or when the user clearly asked for production implementation.
|
||||||
|
|
||||||
|
Loop
|
||||||
|
|
||||||
|
1. Question: state the concrete feasibility question.
|
||||||
|
2. Research: read enough docs/source to choose credible approach.
|
||||||
|
3. Build: create the smallest runnable artifact that proves or kills the idea.
|
||||||
|
4. Stress: try one edge case or failure mode.
|
||||||
|
5. Verdict: `VALIDATED`, `PARTIAL`, or `INVALIDATED`.
|
||||||
|
|
||||||
|
Output shape
|
||||||
|
|
||||||
|
- Default workspace: `/tmp/openclaw-spikes/<slug>` unless user asks for repo-local files.
|
||||||
|
- Repo-local option: `spikes/<NNN-slug>/` with `README.md` and minimal code.
|
||||||
|
- Prefer runnable CLI, tiny HTML, one endpoint, or focused test.
|
||||||
|
- Avoid package sprawl, Docker, env files, app frameworks, and production cleanup.
|
||||||
|
|
||||||
|
Multi-spike ideas
|
||||||
|
|
||||||
|
- Split into 2-5 independent questions.
|
||||||
|
- Run the riskiest question first.
|
||||||
|
- For A/B comparisons, keep inputs equal and measure the same dimensions.
|
||||||
|
- Ask before building all variants if the work is more than a small prototype.
|
||||||
|
|
||||||
|
Verdict format
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Verdict: VALIDATED | PARTIAL | INVALIDATED
|
||||||
|
|
||||||
|
Question: ...
|
||||||
|
Evidence: exact command/output/measurement.
|
||||||
|
What worked: ...
|
||||||
|
What failed or surprised us: ...
|
||||||
|
Recommendation: ship / adjust / avoid, with the next production step.
|
||||||
|
```
|
||||||
|
|
||||||
|
Rules
|
||||||
|
|
||||||
|
- A failed spike is useful when it kills a bad path with evidence.
|
||||||
|
- Do not merge spike code into production without rewriting it normally.
|
||||||
|
- If external dependencies are evaluated, check health: recent release/commit, docs, license, install friction.
|
||||||
Reference in New Issue
Block a user