From a2ea4472f12adb5a368fcbb18eac325f398bad03 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 17 Apr 2026 06:00:09 +0800 Subject: [PATCH] fix(openclaw): make native skills codex-friendly (#864) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Normalizes YAML frontmatter on the 4 hand-authored OpenClaw skills so stricter parsers like Codex can load them. Codex CLI was rejecting these files with "mapping values are not allowed in this context" on colons inside unquoted description scalars. - Drops non-standard `version` and `metadata` fields - Rewrites descriptions into simple "Use when..." form (no inline colons) - Adds a regression test enforcing strict frontmatter (name + description only) Verified live: Codex CLI now loads the skills without errors. Observed during /codex outside-voice run on the eval-community-prs plan review — Codex stderr tripped on these exact files, which was real-world confirmation the fix is needed. Dropped the connect-chrome changes from the original PR (the symlink removal is out of scope for this fix; keeping connect-chrome -> open-gstack-browser). Co-Authored-By: Cathryn Lavery Co-Authored-By: Claude Opus 4.7 (1M context) --- .../gstack-openclaw-ceo-review/SKILL.md | 5 +-- .../gstack-openclaw-investigate/SKILL.md | 4 +-- .../gstack-openclaw-office-hours/SKILL.md | 7 ++-- .../skills/gstack-openclaw-retro/SKILL.md | 9 +---- test/openclaw-native-skills.test.ts | 35 +++++++++++++++++++ 5 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 test/openclaw-native-skills.test.ts diff --git a/openclaw/skills/gstack-openclaw-ceo-review/SKILL.md b/openclaw/skills/gstack-openclaw-ceo-review/SKILL.md index a11f1581..c0b191cf 100644 --- a/openclaw/skills/gstack-openclaw-ceo-review/SKILL.md +++ b/openclaw/skills/gstack-openclaw-ceo-review/SKILL.md @@ -1,8 +1,6 @@ --- name: gstack-openclaw-ceo-review -description: CEO/founder-mode plan review. Rethink the problem, find the 10-star product, challenge premises, expand scope when it creates a better product. Four modes: SCOPE EXPANSION (dream big), SELECTIVE EXPANSION (hold scope + cherry-pick), HOLD SCOPE (maximum rigor), SCOPE REDUCTION (strip to essentials). Use when asked to review a plan, challenge this, CEO review, poke holes, think bigger, or expand scope. -version: 1.0.0 -metadata: { "openclaw": { "emoji": "👑" } } +description: Use when asked to review a plan, challenge a proposal, run a CEO review, poke holes in an approach, think bigger about scope, or decide whether to expand or reduce the plan. --- # CEO Plan Review @@ -129,7 +127,6 @@ Once selected, commit fully. Do not silently drift. **Anti-skip rule:** Never condense, abbreviate, or skip any review section regardless of plan type. If a section genuinely has zero findings, say "No issues found" and move on, but you must evaluate it. Ask the user about each issue ONE AT A TIME. Do NOT batch. -**Reminder: Do NOT make any code changes. Review only.** ### Section 1: Architecture Review Evaluate system design, component boundaries, data flow (all four paths), state machines, coupling, scaling, security architecture, production failure scenarios, rollback posture. Draw dependency graphs. diff --git a/openclaw/skills/gstack-openclaw-investigate/SKILL.md b/openclaw/skills/gstack-openclaw-investigate/SKILL.md index e83d9cda..829476f9 100644 --- a/openclaw/skills/gstack-openclaw-investigate/SKILL.md +++ b/openclaw/skills/gstack-openclaw-investigate/SKILL.md @@ -1,8 +1,6 @@ --- name: gstack-openclaw-investigate -description: Systematic debugging with root cause investigation. Four phases: investigate, analyze, hypothesize, implement. Iron Law: no fixes without root cause. Use when asked to debug, fix a bug, investigate an error, or root cause analysis. Proactively use when user reports errors, stack traces, unexpected behavior, or says something stopped working. -version: 1.0.0 -metadata: { "openclaw": { "emoji": "🔍" } } +description: Use when asked to debug, fix a bug, investigate an error, or do root cause analysis, and when users report errors, stack traces, unexpected behavior, or say something stopped working. --- # Systematic Debugging diff --git a/openclaw/skills/gstack-openclaw-office-hours/SKILL.md b/openclaw/skills/gstack-openclaw-office-hours/SKILL.md index 942f0d6d..9d52b313 100644 --- a/openclaw/skills/gstack-openclaw-office-hours/SKILL.md +++ b/openclaw/skills/gstack-openclaw-office-hours/SKILL.md @@ -1,8 +1,6 @@ --- name: gstack-openclaw-office-hours -description: Product interrogation with six forcing questions. Two modes: startup diagnostic (demand reality, status quo, desperate specificity, narrowest wedge, observation, future-fit) and builder brainstorm. Use when asked to brainstorm, "is this worth building", "I have an idea", "office hours", or "help me think through this". Proactively use when user describes a new product idea or wants to think through design decisions before any code is written. -version: 1.0.0 -metadata: { "openclaw": { "emoji": "🎯" } } +description: Use when asked to brainstorm, evaluate whether an idea is worth building, run office hours, or think through a new product idea or design direction before any code is written. --- # YC Office Hours @@ -281,8 +279,7 @@ Count the signals for the closing message. ## Phase 5: Design Doc -Write the design document and save it to memory. After writing, tell the user: -**"Design doc saved. Other skills (/plan-ceo-review, /plan-eng-review) will find it automatically."** +Write the design document and save it to memory. ### Startup mode design doc template: diff --git a/openclaw/skills/gstack-openclaw-retro/SKILL.md b/openclaw/skills/gstack-openclaw-retro/SKILL.md index 247a94d6..eefc9818 100644 --- a/openclaw/skills/gstack-openclaw-retro/SKILL.md +++ b/openclaw/skills/gstack-openclaw-retro/SKILL.md @@ -1,8 +1,6 @@ --- name: gstack-openclaw-retro -description: Weekly engineering retrospective. Analyzes commit history, work patterns, and code quality metrics with persistent history and trend tracking. Team-aware with per-person contributions, praise, and growth areas. Use when asked for weekly retro, what shipped this week, or engineering retrospective. -version: 1.0.0 -metadata: { "openclaw": { "emoji": "📊" } } +description: "Weekly engineering retrospective. Analyzes commit history, work patterns, and code quality metrics with persistent history and trend tracking. Team-aware with per-person contributions, praise, and growth areas. Use when asked for weekly retro, what shipped this week, or engineering retrospective." --- # Weekly Engineering Retrospective @@ -25,11 +23,6 @@ Parse the argument to determine the time window. Default to 7 days. All times sh --- -### Non-git context (optional) - -Check memory for non-git context: meeting notes, calendar events, decisions, and other -context that doesn't appear in git history. If found, incorporate into the retro narrative. - ### Step 1: Gather Raw Data First, fetch origin and identify the current user: diff --git a/test/openclaw-native-skills.test.ts b/test/openclaw-native-skills.test.ts new file mode 100644 index 00000000..009b5e22 --- /dev/null +++ b/test/openclaw-native-skills.test.ts @@ -0,0 +1,35 @@ +import { describe, test, expect } from 'bun:test'; +import * as fs from 'fs'; +import * as path from 'path'; + +const ROOT = path.resolve(import.meta.dir, '..'); + +const OPENCLAW_NATIVE_SKILLS = [ + 'openclaw/skills/gstack-openclaw-investigate/SKILL.md', + 'openclaw/skills/gstack-openclaw-office-hours/SKILL.md', + 'openclaw/skills/gstack-openclaw-ceo-review/SKILL.md', + 'openclaw/skills/gstack-openclaw-retro/SKILL.md', +]; + +function extractFrontmatter(content: string): string { + expect(content.startsWith('---\n')).toBe(true); + const fmEnd = content.indexOf('\n---', 4); + expect(fmEnd).toBeGreaterThan(0); + return content.slice(4, fmEnd); +} + +describe('OpenClaw native skills', () => { + test('frontmatter parses as YAML and keeps only name + description', () => { + for (const skill of OPENCLAW_NATIVE_SKILLS) { + const content = fs.readFileSync(path.join(ROOT, skill), 'utf-8'); + const frontmatter = extractFrontmatter(content); + const parsed = Bun.YAML.parse(frontmatter) as Record; + + expect(Object.keys(parsed).sort()).toEqual(['description', 'name']); + expect(typeof parsed.name).toBe('string'); + expect(typeof parsed.description).toBe('string'); + expect((parsed.name as string).length).toBeGreaterThan(0); + expect((parsed.description as string).length).toBeGreaterThan(0); + } + }); +});