From b7dfe0b383d0cfd1fdc68bd8e5ade5b426c3d47f Mon Sep 17 00:00:00 2001 From: pannal Date: Sun, 30 Aug 2026 02:40:24 +0100 Subject: [PATCH] Add standalone Codex skill installation --- .github/checks.py | 15 ++++++- .github/workflows/checks.yml | 21 +++++++++ README.md | 23 +++++++--- install.ps1 | 36 +++++++++++----- install.sh | 60 +++++++++++++++++++++----- skills/fable-domain/SKILL.md | 2 +- skills/fable-domain/agents/openai.yaml | 4 ++ skills/fable-judge/SKILL.md | 2 +- skills/fable-judge/agents/openai.yaml | 4 ++ skills/fable-loop/agents/openai.yaml | 4 ++ skills/fable-method/SKILL.md | 1 - skills/fable-method/agents/openai.yaml | 4 ++ 12 files changed, 147 insertions(+), 29 deletions(-) create mode 100644 skills/fable-domain/agents/openai.yaml create mode 100644 skills/fable-judge/agents/openai.yaml create mode 100644 skills/fable-loop/agents/openai.yaml create mode 100644 skills/fable-method/agents/openai.yaml diff --git a/.github/checks.py b/.github/checks.py index 0cc102d..3099aaf 100644 --- a/.github/checks.py +++ b/.github/checks.py @@ -48,7 +48,7 @@ def ok(msg): except Exception as e: fail(f"version check: {e}") -# 3. All four skills exist with frontmatter name + description +# 3. All four skills exist with frontmatter name + description and Codex metadata for skill in ["fable-method", "fable-loop", "fable-judge", "fable-domain"]: path = os.path.join(ROOT, "skills", skill, "SKILL.md") try: @@ -61,6 +61,19 @@ def ok(msg): except Exception as e: fail(f"skills/{skill}/SKILL.md: {e}") + metadata_path = os.path.join(ROOT, "skills", skill, "agents", "openai.yaml") + try: + with io.open(metadata_path, encoding="utf-8") as f: + metadata = f.read() + required = ["interface:", "display_name:", "short_description:", "default_prompt:"] + missing = [field for field in required if field not in metadata] + if missing or f"${skill}" not in metadata: + fail(f"skills/{skill}/agents/openai.yaml: missing fields or skill prompt") + else: + ok(f"skills/{skill}/agents/openai.yaml valid") + except Exception as e: + fail(f"skills/{skill}/agents/openai.yaml: {e}") + # 4. Domain adapters all carry a binding minimum evidence set and a fraud table domains_dir = os.path.join(ROOT, "skills", "fable-method", "references", "domains") for name in sorted(os.listdir(domains_dir)): diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b89753b..80b850e 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -13,3 +13,24 @@ jobs: python-version: "3.12" - name: Validate manifests, skills, adapters, evidence, and style run: python .github/checks.py + - name: Smoke-test Bash installers + run: | + claude_home="$(mktemp -d)" + bash install.sh --claude --dest "$claude_home/skills" + test -f "$claude_home/skills/fable-domain/SKILL.md" + codex_home="$(mktemp -d)" + CODEX_HOME="$codex_home" bash install.sh --codex + test -f "$codex_home/skills/fable-domain/SKILL.md" + test -f "$codex_home/skills/fable-method/agents/openai.yaml" + - name: Smoke-test PowerShell Codex installer + shell: pwsh + run: | + $claudeSkills = Join-Path $env:RUNNER_TEMP "fable-claude-skills" + $codexSkills = Join-Path $env:RUNNER_TEMP "fable-codex-skills" + ./install.ps1 -Target claude -Destination $claudeSkills + ./install.ps1 -Target codex -Destination $codexSkills + foreach ($destination in @($claudeSkills, $codexSkills)) { + if (-not (Test-Path (Join-Path $destination "fable-domain/SKILL.md"))) { + throw "fable-domain was not installed into $destination" + } + } diff --git a/README.md b/README.md index c19d24b..7f58d56 100644 --- a/README.md +++ b/README.md @@ -80,15 +80,27 @@ Seven more charts (ask classification with tie-breaks, the bounded evidence loop All four skills arrive namespaced (`/fable:fable-method`, `/fable:fable-loop`, `/fable:fable-judge`, `/fable:fable-domain`), versioned, and updatable via `/plugin marketplace update`. -**As standalone skills** (un-namespaced `/fable-method` etc.): +**As standalone Claude Code skills** (un-namespaced `/fable-method` etc.): ```bash -git clone https://github.com/Sahir619/fable-method && bash fable-method/install.sh +git clone https://github.com/Sahir619/fable-method && bash fable-method/install.sh --claude ``` -Windows PowerShell: `git clone https://github.com/Sahir619/fable-method; .\fable-method\install.ps1` +Windows PowerShell: `git clone https://github.com/Sahir619/fable-method; .\fable-method\install.ps1 -Target claude` -**Any other agent** (Codex, Cursor, aider, a raw system prompt): use [AGENTS.md](AGENTS.md), the identical method without Claude-specific frontmatter. +**As Codex skills:** + +```bash +git clone https://github.com/Sahir619/fable-method && bash fable-method/install.sh --codex +``` + +Windows PowerShell: `git clone https://github.com/Sahir619/fable-method; .\fable-method\install.ps1 -Target codex` + +All four skills are installed into `$CODEX_HOME/skills`, or `~/.codex/skills` when `CODEX_HOME` is unset. They are available to Codex in a new turn. + +Both installers accept a custom destination for isolated or project-specific installs: `--dest PATH` in Bash or `-Destination PATH` in PowerShell. + +**Any other agent** (Cursor, aider, a raw system prompt): use [AGENTS.md](AGENTS.md), the identical method without product-specific frontmatter. **Make it proactive (recommended).** Skills fire best when nobody has to remember them. Add to your global `~/.claude/CLAUDE.md`: @@ -166,9 +178,10 @@ skills/ fable-loop/ the orchestrated plan-execute-verify-audit workflow fable-judge/ adversarial verification of finished work + trap suite fable-domain/ generates new domain adapter bundles (adapter + trap + smoke eval) + */agents/openai.yaml optional Codex display metadata for each skill AGENTS.md the same method for any other harness DOC.md plain-language explainer: the flow, what changed since 1.3, why it is better -install.sh / install.ps1 standalone-skill install into ~/.claude/skills/ (plugin preferred) +install.sh / install.ps1 standalone install into Claude Code or Codex skill directories eval/ README.md methodology + how to reproduce RESULTS.md dated round-by-round results log (wins, nulls, and failures) diff --git a/install.ps1 b/install.ps1 index 753e4de..a40e9b9 100644 --- a/install.ps1 +++ b/install.ps1 @@ -1,15 +1,31 @@ -# Manual installer (Windows PowerShell) for users who prefer standalone -# skills over the plugin. Plugin install (recommended): inside Claude Code run -# /plugin marketplace add Sahir619/fable-method -# /plugin install fable@fable-method +param( + [ValidateSet("claude", "codex")] + [string]$Target = "claude", + [string]$Destination +) + +# Standalone skill installer for Windows PowerShell. +# Usage: .\install.ps1 [-Target claude|codex] [-Destination PATH] $ErrorActionPreference = "Stop" $src = $PSScriptRoot -$dst = Join-Path $HOME ".claude\skills" + +if ($Destination) { + $dst = $Destination + $product = if ($Target -eq "codex") { "Codex" } else { "Claude Code" } +} elseif ($Target -eq "codex") { + $codexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $HOME ".codex" } + $dst = Join-Path $codexHome "skills" + $product = "Codex" +} else { + $dst = Join-Path $HOME ".claude\skills" + $product = "Claude Code" +} New-Item -ItemType Directory -Force -Path $dst | Out-Null -Copy-Item (Join-Path $src "skills\fable-method") $dst -Recurse -Force -Copy-Item (Join-Path $src "skills\fable-loop") $dst -Recurse -Force -Copy-Item (Join-Path $src "skills\fable-judge") $dst -Recurse -Force +$skills = @("fable-method", "fable-loop", "fable-judge", "fable-domain") +foreach ($skill in $skills) { + Copy-Item (Join-Path $src "skills\$skill") $dst -Recurse -Force +} -Write-Host "Installed: fable-method, fable-loop, fable-judge -> $dst" -Write-Host "Try it: open Claude Code and type /fable-judge after any agent claims work is done." +Write-Host "Installed: $($skills -join ' ') -> $dst" +Write-Host "The skills will be available to $product in a new turn." diff --git a/install.sh b/install.sh index ed7eba5..c349c78 100644 --- a/install.sh +++ b/install.sh @@ -1,16 +1,56 @@ #!/usr/bin/env bash -# Manual installer (macOS / Linux / Git Bash) for users who prefer standalone -# skills over the plugin. Plugin install (recommended): inside Claude Code run -# /plugin marketplace add Sahir619/fable-method -# /plugin install fable@fable-method +# Standalone skill installer for macOS, Linux, and Git Bash. +# Usage: ./install.sh [--claude|--codex] [--dest PATH] set -euo pipefail + src="$(cd "$(dirname "$0")" && pwd)" -dst="$HOME/.claude/skills" +target="--claude" +destination="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --claude|--codex) + target="$1" + shift + ;; + --dest) + if [[ $# -lt 2 ]]; then + echo "--dest requires a path" >&2 + exit 2 + fi + destination="$2" + shift 2 + ;; + --help|-h) + echo "Usage: $0 [--claude|--codex] [--dest PATH]" + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + echo "Usage: $0 [--claude|--codex] [--dest PATH]" >&2 + exit 2 + ;; + esac +done + +case "$target" in + --claude) + default_destination="$HOME/.claude/skills" + product="Claude Code" + ;; + --codex) + default_destination="${CODEX_HOME:-$HOME/.codex}/skills" + product="Codex" + ;; +esac + +dst="${destination:-$default_destination}" +skills=(fable-method fable-loop fable-judge fable-domain) mkdir -p "$dst" -cp -r "$src/skills/fable-method" "$dst/" -cp -r "$src/skills/fable-loop" "$dst/" -cp -r "$src/skills/fable-judge" "$dst/" +for skill in "${skills[@]}"; do + cp -r "$src/skills/$skill" "$dst/" +done -echo "Installed: fable-method, fable-loop, fable-judge -> $dst" -echo "Try it: open Claude Code and type /fable-judge after any agent claims work is done." +echo "Installed: ${skills[*]} -> $dst" +echo "The skills will be available to $product in a new turn." diff --git a/skills/fable-domain/SKILL.md b/skills/fable-domain/SKILL.md index 8a45cd5..25f3e2a 100644 --- a/skills/fable-domain/SKILL.md +++ b/skills/fable-domain/SKILL.md @@ -1,6 +1,6 @@ --- name: fable-domain -description: Discuss a domain with the user, research it from real sources, then generate a trusted skill bundle for it - a step-by-step workflow with a flowchart, a domain adapter, a trap fixture, and a smoke eval. Use when the user says "/fable-domain ", "make a skill for ", "add a domain to the fable method", or "give a lesser model Fable's workflow for ". The bundle is the deliverable; a workflow without its flowchart, sources, and trap is not done. +description: Discuss a domain with the user, research it from real sources, then generate a trusted skill bundle for it - a step-by-step workflow with a flowchart, a domain adapter, a trap fixture, and a smoke eval. Use when the user says "/fable-domain SECTOR", "make a skill for DOMAIN", "add a domain to the fable method", or "give a lesser model Fable's workflow for DOMAIN". The bundle is the deliverable; a workflow without its flowchart, sources, and trap is not done. --- # fable-domain diff --git a/skills/fable-domain/agents/openai.yaml b/skills/fable-domain/agents/openai.yaml new file mode 100644 index 0000000..ccf491e --- /dev/null +++ b/skills/fable-domain/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Fable Domain" + short_description: "Build a researched domain workflow" + default_prompt: "Use $fable-domain to build a researched workflow and trap-based evaluation for this domain." diff --git a/skills/fable-judge/SKILL.md b/skills/fable-judge/SKILL.md index 9335fd3..480d2c6 100644 --- a/skills/fable-judge/SKILL.md +++ b/skills/fable-judge/SKILL.md @@ -1,6 +1,6 @@ --- name: fable-judge -description: Adversarial verification of finished work. Treats any "done" as a set of claims, then re-runs the claimed verifications, diffs what actually changed, detects weakened tests and false completion claims, and delivers an evidence-based verdict (VERIFIED / VERIFIED WITH CAVEATS / REFUTED). Use after any agent or model claims work is complete - "/fable-judge", "judge this work", "verify what it did", "did that actually work?". Also runs the fable-method trap suite against a skill or model via "/fable-judge suite ". +description: Adversarial verification of finished work. Treats any "done" as a set of claims, then re-runs the claimed verifications, diffs what actually changed, detects weakened tests and false completion claims, and delivers an evidence-based verdict (VERIFIED / VERIFIED WITH CAVEATS / REFUTED). Use after any agent or model claims work is complete - "/fable-judge", "judge this work", "verify what it did", "did that actually work?". Also runs the fable-method trap suite against a skill or model via "/fable-judge suite TARGET". --- # fable-judge diff --git a/skills/fable-judge/agents/openai.yaml b/skills/fable-judge/agents/openai.yaml new file mode 100644 index 0000000..23128f9 --- /dev/null +++ b/skills/fable-judge/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Fable Judge" + short_description: "Verify completed work against evidence" + default_prompt: "Use $fable-judge to verify the completed work and report an evidence-based verdict." diff --git a/skills/fable-loop/agents/openai.yaml b/skills/fable-loop/agents/openai.yaml new file mode 100644 index 0000000..d3e4147 --- /dev/null +++ b/skills/fable-loop/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Fable Loop" + short_description: "Run an end-to-end verified workflow" + default_prompt: "Use $fable-loop to plan, execute, and verify this task end to end." diff --git a/skills/fable-method/SKILL.md b/skills/fable-method/SKILL.md index ca11554..32195a2 100644 --- a/skills/fable-method/SKILL.md +++ b/skills/fable-method/SKILL.md @@ -1,7 +1,6 @@ --- name: fable-method description: A step-by-step problem-solving loop (classify the ask, define done, gather evidence, decide, act surgically, verify by observation, report outcome-first). Use when the user says "/fable-method", "use the fable method", or "approach this like Fable", or proactively when starting any multi-step task that no task-specific skill covers. Subcommands - plan (stop after the plan), audit (grade finished work against the loop), report (rewrite an answer outcome-first). -trigger: /fable-method --- # The Fable Method diff --git a/skills/fable-method/agents/openai.yaml b/skills/fable-method/agents/openai.yaml new file mode 100644 index 0000000..f9c0aec --- /dev/null +++ b/skills/fable-method/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Fable Method" + short_description: "Structured evidence-first problem solving" + default_prompt: "Use $fable-method to solve this task with explicit evidence and verification."